<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
    <id>urn:uuid:476e668a-1c79-e63f-d0e1-ef4c5ac3683a</id>
    <title>Stéphane HUC :: IT Log</title>
    <subtitle>Documentations Administration Système, Réseaux par Stéphane HUC</subtitle>
    <link href="http://doc.huc.fr.eu.org/fr/atom.xml" rel="self" type="application/atom+xml" />
    <link href="http:/doc.huc.fr.eu.org/en/atom/xml" hreflang="en" rel="alternate" type="application/atom+xml" />
    <link href="http://creativecommons.org/publicdomain/zero/1.0/legalcode.fr" hreflang="fr" rel="license" />
    <link href="http://creativecommons.org/publicdomain/zero/1.0/deed.fr" hreflang="fr" rel="license" />
    <link href="http://doc.huc.fr.eu.org/opensearch.xml" rel="search" type="application/opensearchdescription+xml" title="HUC Websearch fr" />
    <rights>2026Stéphane HUC</rights>
    <icon>/img/favicon.ico</icon>
    <logo>/svg/Logo_final.svg</logo>
    <updated>2026-03-08T02:41:09+01:00</updated>
    <author>
        <name>Stéphane HUC</name>
        <email>consult+hugo@huc.fr.eu.org</email>
        <uri>http://doc.huc.fr.eu.org/fr/</uri>
    </author>
    <generator uri="https://gohugo.io" version="0.157.0">Hugo</generator>
    <entry>
        <id>urn:uuid:1aa16bd3-2cb8-f0c3-c9a6-1f22d33bdf75</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/amdgpu-rocm-opencl/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Ajouter le support d&#39;OpenCL pour les GPU AMD Radeon (amdgpu &#43; ROCm = OpenCL, OpenMP, HIP support)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="amdgpu" scheme="http://doc.huc.fr.eu.org/fr/tags/amdgpu/" />
        <category term="ROCm" scheme="http://doc.huc.fr.eu.org/fr/tags/rocm/" />
        <category term="OpenCL" scheme="http://doc.huc.fr.eu.org/fr/tags/opencl/" />
        <category term="OpenMP" scheme="http://doc.huc.fr.eu.org/fr/tags/openmp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Environnement de test :</p>
<ul>
<li>OS : Debian Sid</li>
<li>Logiciels : <a title="Linux GPU Configuration And Monitoring Tool" href="https://github.com/ilya-zlobintsev/LACT" rel="external">LACT</a> ; <a href="https://www.ocbase.com/download" rel="external">OCCT</a></li>
<li>Matériel : AMD Radeon RX 7600 XT</li>
</ul>
<p>Pour faire fonctionner une carte AMD Radeon RX, il est nécessaire d&rsquo;utiliser le
pilote <code>amdgpu</code> ; ceci est d&rsquo;ailleurs aussi valable si vous avez un APU AMD Ryzen.</p>
<p>Mais pour pouvoir utiliser les frameworks logiciels, tel OpenCL, il faut en plus
installer le paquet logiciel <code>rocm-opencl-icd</code> qui se trouve être dans les dépôts
officiels Debian depuis quelque temps.</p>
<p>Et, oui, bien que ne faisant par partie des matériels officiellement supportés,
la carte RX 7600 XT utilise bien OpenCL.</p>
<p>Vous pouvez aussi ajouter l&rsquo;utilitaire <code>clinfo</code> qui informe du support de votre
matériel.</p>
<h2 id="configuration">Configuration</h2>
<p>Ajouter votre utilisateur aux groupes <code>render</code> et <code>video</code>, puis redémarrer la
session.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71">#: usermod -a -G render,video $LOGNAME</span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<ul>
<li>
<p>La <a href="https://rocm.docs.amd.com/en/latest/" rel="external">documentation de ROCm</a> :</p>
<ul>
<li>la page <a href="https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html" rel="external">System requirements (Linux)</a> qui permet de voir les requis matériels sous Linux, où le support
est officiel à partir de la Radeon RX 7700, et ce depuis Debian 12 &ldquo;Bookworm&rdquo;.</li>
</ul>
</li>
<li>
<p>Le <a href="https://manpages.debian.org/unstable/manpages-fr/logname.1.fr.html" rel="external">manpage logname(1) FR</a></p>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>la page <a href="https://math.dartmouth.edu/~sarunas/amdgpu-opencl.html" rel="external"><strong>OpenCL with the open-source amdgpu kernel module</strong></a></li>
</ul>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Ajouter le support logiciels des frameworks OpenCL, OpenMP, HIP au pilote amdgpu sous Debian Sid]]></summary>
        <published>2026-02-24T13:46:26+01:00</published>
        <updated>2026-02-24T18:08:50+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b14f656f-af56-b8a9-e894-6e7c2cbc764e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/factory-reset/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Factory Reset</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="Dépannage" scheme="http://doc.huc.fr.eu.org/fr/tags/d%C3%A9pannage/" />
        <category term="Usine" scheme="http://doc.huc.fr.eu.org/fr/tags/usine/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention tous les paramètres seront absolument supprimés, il faudra se connecter
à l&rsquo;interface accessible par défaut sur l&rsquo;adresse IP <code>192.168.1.1</code> <em>(ce qui peut
poser problème si votre routeur principal a la même adresse IP ; veillez à le
faire hors réseau)</em>.</div>

<p>Restaurer les paramètres par défaut est simple en soit.</p>
<p>⇒ En mode CLI, il y a deux possibilités de restauration par défaut :</p>
<ul>
<li>
<p>Le mode <strong>Soft</strong> : il suffit d&rsquo;utiliser la commande <code>firstboot</code> puis de
redémarrer la machine, tel que : <code># firsboot &amp;&amp; reboot</code></p>
<p>Il peut y avoir dans certains cas un soucis avec l&rsquo;exécution de la commande
<code>firstboot</code> ; dans ce cas essayez avec l&rsquo;option <code>-y</code> et d&rsquo;exécuter la
commande <code>reboot</code> sur une ligne séparée.</p>
</li>
<li>
<p>Le mode <strong>Hard</strong> :</p>
<ul>
<li>
<p>Exécutez en premier lieu la commande <code>sysupgrade</code> pour réinstaller
n&rsquo;importe quel firmware</p>
</li>
<li>
<p>Réinitialiser la partition JFFS2 :
<code># umount /overlay &amp;&amp; jffs2reset &amp;&amp; reboot</code></p>
</li>
<li>
<p>puis réinitialiser partition FFS2 :
<code># dd if=/dev/zero of=/dev/loop0 bs=1M; reboot</code></p>
</li>
</ul>
</li>
</ul>
<p>⇒ Depuis l&rsquo;interface LUCI, cliquez sur le menu <strong>System</strong> &gt; <strong>Backup / Flash firmware</strong>,
puis dans la section <strong>Restore</strong>, cliquez sur le bouton rouge titré
<span class="red">[ Perform reset ]</span>
.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://openwrt.org/docs/guide-user/troubleshooting/failsafe_and_factory_reset#factory_reset" rel="external">OpenWRT Failsafe mode, factory reset, and recovery mode</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment restaurer par défaut les paramètres systèmes d&#39;OpenWRT, en mode usine.]]></summary>
        <published>2025-09-23T18:46:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:52a4ebd4-2dde-f844-85fa-ecde557f5ea2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/wifi-repeter/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Créer un répéteur WIFI</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="Wifi" scheme="http://doc.huc.fr.eu.org/fr/tags/wifi/" />
        <category term="répéteur" scheme="http://doc.huc.fr.eu.org/fr/tags/r%C3%A9p%C3%A9teur/" />
        <category term="point" scheme="http://doc.huc.fr.eu.org/fr/tags/point/" />
        <category term="accès" scheme="http://doc.huc.fr.eu.org/fr/tags/acc%C3%A8s/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Transformer son routeur sous OpenWRT en point d&rsquo;accès (répéteur) est assez simple
en soit ; cela va impacter principalement trois des fichiers du système :</p>
<ul>
<li><a href="https://openwrt.org/docs/guide-user/network/network_configuration" rel="external">/etc/config/network</a></li>
<li><a href="https://openwrt.org/docs/guide-user/base-system/dhcp" rel="external">/etc/config/dhcp</a></li>
<li><a href="https://openwrt.org/docs/guide-user/network/wifi/basic" rel="external">/etc/config/wireless</a></li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Il est important de partir sur une base d&rsquo;OpenWRT fraîchement installée, voire
de réinitialiser les 
<a class="inside" href="/fr/sys/openwrt/factory-reset/" title="Lien interne vers l&#39;article : 'OpenWRT : Factory Reset'">paramètres en mode usine</a>

par défaut.</p>
<hr>
<p>La première chose à faire est de <strong>connecter physiquement par cable réseau le
routeur qui sera répéteur wifi au routeur principal</strong>, puis ensuite de modifier
la configuration du répéteur wifi. Ainsi, c&rsquo;est le serveur DHCP du routeur principal
qui enverra les paquets nécessaires pour permettre la connexion réseau wifi par
le biais du point d&rsquo;accès.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Vérifiez absolument que le câble réseau qui vient du routeur principal ne soit
connecté QUE sur un des ports LAN de votre répéteur, et non pas sur le port WAN.
Par défaut, si c&rsquo;était le cas, la future configuration ne serait pas fonctionnelle !</div>

<hr>
<p>Comme bien souvent, sous OpenWRT, il est possible de le faire de manières différentes,
en éditant en mode CLI les fichiers concernés, ou de passer par l&rsquo;interface LUCI.</p>
<p>Cet article se focalise sur la manière CLI.</p>
<h3 id="cli">CLI</h3>
<h4 id="network">network</h4>
<p>Editez en premier le fichier <code>/etc/config/network</code> pour que la configuration de
l&rsquo;interface <code>lan</code> soit le futur point d&rsquo;accès dans votre réseau actuel, tel que
pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">config interface &#39;lan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option device &#39;br-lan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option proto &#39;static&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ipaddr &#39;192.168.1.3&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option netmask &#39;255.255.255.0&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#    option ip6assign &#39;60&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option gateway &#39;192.168.1.1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list dns &#39;192.168.1.1&#39;</span>
</span></span></code></pre></div><hr>
<p>La commande <code>uci</code> nous permet de la modifier directement :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci batch &lt;&lt; EOF
    set network.lan.dns=&#39;192.168.1.1&#39;
    set network.lan.ipaddr=&#39;192.168.1.3&#39;
    set network.lan.netmask=&#39;255.255.255.0&#39;
    set network.lan.gateway=&#39;192.168.1.1&#39;
    set network.lan.proto=&#39;static&#39;
EOF
uci commit
</code></pre><h4 id="wireless">wireless</h4>
<p>Maintenant il faut éditer le fichier <code>/etc/config/wireless</code> la ou les sections
<code>wifi-device</code> et <code>wifi-iface</code> pour changer les paramètres SSID, type de chiffrement,
passphrase nécessaire, le code pays, puis pour finir par activer le module radio.</p>
<p>Voici pour l&rsquo;exemple sur un routeur Xiaomi AX3000T, qui comporte deux modules
radio :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># cat /etc/config/wireless</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">config wifi-device &#39;radio0&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option type &#39;mac80211&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option path &#39;platform/soc/18000000.wifi&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option channel &#39;1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option band &#39;2g&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option htmode &#39;HT20&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option country &#39;FR&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option cell_density &#39;0&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">config wifi-device &#39;radio1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option type &#39;mac80211&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option path &#39;platform/soc/18000000.wifi+1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option channel &#39;36&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option band &#39;5g&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option htmode &#39;HE80&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option country &#39;FR&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option cell_density &#39;0&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">config wifi-iface &#39;wifinet0&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option device &#39;radio0&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option mode &#39;ap&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ssid &#39;***&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option encryption &#39;sae-mixed&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option dtim_period &#39;3&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option key &#39;***&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option ieee80211r &#39;1&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option mobility_domain &#39;4772&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ft_over_ds &#39;0&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option network &#39;lan&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">config wifi-iface &#39;wifinet1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option device &#39;radio1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option mode &#39;ap&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ssid &#39;***&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option encryption &#39;sae&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option dtim_period &#39;3&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option key &#39;***&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option ieee80211r &#39;1&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option mobility_domain &#39;4772&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ft_over_ds &#39;0&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option wpa_disable_eapol_key_retries &#39;1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option network &#39;lan&#39;</span>
</span></span></code></pre></div><ul>
<li>
<p>Remarquez dans les deux sections <code>wifi-device</code> l&rsquo;option de pays paramétrée pour
la france : <code>option country 'FR'</code>.</p>
</li>
<li>
<p>Les deux sections <code>wifi-iface</code> concernant chacun des deux modules radio sont
bien paramétrées en <code>option mode 'ap'</code> et cible bien le réseau lan :
<code>option network 'lan'</code>.</p>
<ul>
<li>Modifiez les <code>option ssid</code>, <code>option encryption</code> et <code>option key</code> selon les
identifiants wifi du routeur Wifi principal, ainsi que l&rsquo;algorythme de
chiffrement utilisé et la clé paramétrée.</li>
</ul>
</li>
<li>
<p>Ici dans l&rsquo;exemple, la section <code>wifi-iface</code> du module <code>radio0</code> est configurée
pour utiliser le chiffrement <strong>WPA2/WPA3 PSK, SAE (CCMP)</strong>, soit
<code>option encryption 'sae-mixed'</code>, ce qui permet à des appareils un peu plus
vieux ou nécessitant absolument l&rsquo;usage de la bande 2G, tout en gardant un
chiffrement WPA2 assez sécurisé, et en permettant que les périphériques wifi
capables de se connecter en WPA3 choisiront ce chiffrement offert par défaut,
alors que celle du module <code>radio1</code> est configurée pour n&rsquo;utiliser que le
chiffrement WPA3.</p>
</li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il est intéressant de configurer, si votre routeur a des modules radio 2G et 5G,
d&rsquo;utiliser les mêmes SSID et protocoles de chiffrement, cela permet au périphérique
client de choisir automatiquement quel est le meilleur protocole pour lui.</div>

<hr>
<p>La commande <code>uci</code> permet de modifier juste le nécessaire :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci batch &lt;&lt; EOF
    set.wireless.wifi_device[0].country=&#39;FR&#39;
    set.wireless.wifi_device[1].country=&#39;FR&#39;

    set.wireless.wifi_iface[0].mode=&#39;ap&#39;
    set.wireless.wifi_iface[1].mode=&#39;ap&#39;

    set.wireless.wifi_iface[0].network=&#39;lan&#39;
    set.wireless.wifi_iface[1].network=&#39;lan&#39;

    set.wireless.wifi_iface[0].encryption=&#39;sae-mixed&#39;
    set.wireless.wifi_iface[1].encryption=&#39;sae&#39;

    set wireless.wifi_iface[0].ssid=&#39;Votre_SSID&#39;
    set.wireless.wifi_iface[1].ssid=&#39;Votre_SSID&#39;

    set wireless.wifi_iface[0].key=&#39;Votre_Passphrase&#39;
    set.wireless.wifi_iface[1].key=&#39;Votre_Passphrase&#39;
EOF
uci commit
</code></pre><h4 id="dhcp">DHCP</h4>
<p>Il est critique de <strong>désactiver l&rsquo;utilisation du serveur DHCP interne</strong> au point
d&rsquo;accès, pour deux raisons :</p>
<ul>
<li><strong>s&rsquo;assurer que seul le serveur DHCP du routeur principal envoie les trames
nécessaires</strong> à la connexion des périphériques wifi</li>
<li>lors des mises-à-jours du point d&rsquo;accès, le serveur DHCP du point d&rsquo;accès va
être réactivé !</li>
</ul>
<hr>
<ol>
<li>Désactivez le serveur DHCP du point d&rsquo;accès se fait, par le biais de LUCI, en
cliquant sur le menu <strong>System</strong> &gt; <strong>Startup</strong> puis de cliquer sur le bouton [ Enable ]
relatif à <strong>dnsmaq</strong> <em>(normalement en ligne 19)</em> pour le désactiver puis
appuyer sur le bouton [ Stop ].</li>
<li>Modifiez le fichier <code>/etc/config/dhcp</code> pour ajouter l&rsquo;option suivante <code>option ignore '1'</code>
dans la section <code>config dhcp 'lan'</code> ; supprimez aussi toutes les options
relatives à IPv6 !</li>
</ol>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">config dhcp &#39;lan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option interface &#39;lan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option start &#39;100&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option limit &#39;150&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option leasetime &#39;12h&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ignore &#39;1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option dhcpv4 &#39;disabled&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option dhcpv6 &#39;disabled&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ndp &#39;disabled&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option ra &#39;disabled&#39;</span>
</span></span></code></pre></div><p>L&rsquo;utilisation de l&rsquo;option <code>ignore</code> activée est le seul moyen actuel de permettre
à ce que le routeur répéteur n&rsquo;utilise absolument que les paquets envoyés par le
serveur DHCP du routeur principal, même si son propre serveur DHCP est actif
<em>(ce qui sera malheureusement le cas lors des mises-à-jours d&rsquo;OpenWRT)</em>.</p>
<hr>
<p>L&rsquo;utilisation de la commande <code>uci</code> :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci batch &lt;&lt; EOF
    set dhcp.lan.ignore=&#39;1&#39;
EOF
uci commit

# Attention à bien assimiler qu&#39;au prochain `sysupgrade`, le service sera à nouveau activé :
service dnsmasq stop
service dnsmasq disable
</code></pre><hr>
<p>Maintenant que ces différentes configurations ont été faites, le plus simple
reste de démarrer le répéteur et de profitez de l&rsquo;usage du wifi.</p>
<h4 id="wan--lan">WAN → LAN</h4>
<p>Transformer le port WAN en port LAN est possible.</p>
<p>Par défaut, les ports WAN et WAN6 sont configurés dans OpenWRT ; il faut donc
supprimer les configurations relatives dans le fichier <code>/etc/config/network</code>
puis ajouter l&rsquo;interface <code>wan</code> au pont <code>br-lan</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">config device</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option name &#39;br-lan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option type &#39;bridge&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list ports &#39;lan1&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list ports &#39;lan2&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list ports &#39;lan3&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list ports &#39;lan4&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">list ports &#39;wan&#39;</span>
</span></span></code></pre></div><p>Et supprimez dans le même fichier les informations relatives à WAN / WAN6 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">config interface &#39;wan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option device &#39;wan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option proto &#39;dhcp&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">config interface &#39;wan6&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option device &#39;wan&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">option proto &#39;dhcpv6&#39;</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Parfois certains matériels sont capricieux avec l&rsquo;utilisation de WAN en tant que
LAN. Dans certaines circonstances, les performances réseaux peuvent diminuer lors
du transfert entre l&rsquo;interface LAN et WAN, voire s&rsquo;effondrer. C&rsquo;est souvent le
cas pour les routeurs logiciellement optimisés pour le routage.</p>
<p>Si malheureusement, une telle baisse de performance s&rsquo;illustre dans votre cas,
le seul reméde est de garder l&rsquo;interface WAN hors du pont et séparée !
Dans ce cas, il faut restaurer le fichier <code>nertwork</code>.</p>
</div>

<hr>
<p>Par le biais d&rsquo;<code>uci</code> :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci batch &lt;&lt; EOF
    set network.@device[0].ports=&#39;lan2&#39; &#39;lan3&#39; &#39;lan4&#39; &#39;wan&#39;
    set network.wan.disabled=&#39;1&#39;
    set network.wan6.disabled=&#39;1&#39;
EOF
uci commit
</code></pre><h3 id="tldr">TL;DR</h3>
<p><strong>À vous de modifier selon votre matériel</strong>, le résumé ci-dessous - <em>pour mieux
comprendre de quoi il s&rsquo;agit, soit vous lisez l&rsquo;ensemble de l&rsquo;article, soit
vous allez sur le documentation officielle</em> !</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci batch &lt;&lt; EOF
    set network.lan.dns=&#39;192.168.1.1&#39;
    set network.lan.ipaddr=&#39;192.168.1.3&#39;
    set network.lan.netmask=&#39;255.255.255.0&#39;
    set network.lan.gateway=&#39;192.168.1.1&#39;
    set network.lan.proto=&#39;static&#39;

    set.wireless.wifi_device[0].country=&#39;FR&#39;
    set.wireless.wifi_device[1].country=&#39;FR&#39;

    set.wireless.wifi_iface[0].mode=&#39;ap&#39;
    set.wireless.wifi_iface[1].mode=&#39;ap&#39;

    set.wireless.wifi_iface[0].network=&#39;lan&#39;
    set.wireless.wifi_iface[1].network=&#39;lan&#39;

    set.wireless.wifi_iface[0].encryption=&#39;sae-mixed&#39;
    set.wireless.wifi_iface[1].encryption=&#39;sae&#39;

    set wireless.wifi_iface[0].ssid=&#39;Votre_SSID&#39;
    set.wireless.wifi_iface[1].ssid=&#39;Votre_SSID&#39;

    set wireless.wifi_iface[0].key=&#39;Votre_Passphrase&#39;
    set.wireless.wifi_iface[1].key=&#39;Votre_Passphrase&#39;

    set dhcp.lan.ignore=&#39;1&#39;
    set dhcp.lan.dhcpv4=&#39;disabled&#39;
    set dhcp.lan.dhcpv6=&#39;disabled&#39;
    set dhcp.lan.ndp=&#39;disabled&#39;
    set dhcp.lan.ra=&#39;disabled&#39;

    set network.@device[0].ports=&#39;lan2&#39; &#39;lan3&#39; &#39;lan4&#39; &#39;wan&#39;
    set network.wan.disabled=&#39;1&#39;
    set network.wan6.disabled=&#39;1&#39;
EOF
uci commit
</code></pre><h2 id="remerciement">Remerciement</h2>
<p>Je tiens à remercier @salim/jdh.net pour ses judicieuses remarques à-propos d&rsquo;<code>uci</code> !</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le guide actuel, en anglais, se trouve sur :
<a href="https://openwrt.org/docs/guide-user/network/wifi/wifiextenders/bridgedap" rel="external">https://openwrt.org/docs/guide-user/network/wifi/wifiextenders/bridgedap</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[OpenWRT : transformer facilement votre routeur en point d&#39;accès Wifi (répéteur), appelé aussi &#39;Point d&#39;accès passif&#39;, &#39;Dumb AP&#39; (en anglais) .]]></summary>
        <published>2025-09-23T16:45:37+02:00</published>
        <updated>2025-11-20T14:51:28+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:879215fd-735b-6de6-0e79-13f176543275</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/openrgb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenRGB : Gestion des matériels RGB</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="RGB" scheme="http://doc.huc.fr.eu.org/fr/tags/rgb/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<figure>
    <a href="/images/openrgb/OpenRGB.png" title="Logo OpenRGB">
    <picture>
        
        <source srcset="/images/openrgb/OpenRGB_hu_54c7a592c89cae0d.webp" type="image/webp">
        
        <img alt="Logo OpenRGB" height="106" loading="lazy" src="/images/openrgb/OpenRGB_hu_c451c8cba0e5dbdd.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Logo OpenRGB</figcaption>
</figure>
<p><strong>OpenRGB</strong> est LE projet Open Source de gestion de différents matériels RGB par
différents fabriquants/vendeurs, complétement indépendants desdits fabriquants.</p>
<p>Il permet de centraliser la gestion, soit par une interface graphique, soit en
mode CLI.</p>
<p>Le projet est multi-plateformes <em>(Linux, MacOS, Windows)</em>, et multi-architectures
<em>(32 et 64 bits, x86 et ARM)</em>.</p>
<p>De même, il existe quelques plugins pour interagir selon différents profils
d&rsquo;événements systèmes.</p>
<ul>
<li>Licence : GNU/GPL v2</li>
<li>Site web : <a href="https://openrgb.org/" rel="external">https://openrgb.org/</a></li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<p>Installons le binaire :</p>
<p>⇒ Debian <em>(et assimilés)</em> : <code>apt install openrgb</code></p>
<p>L&rsquo;interface graphique se situe normalement, depuis le menu <strong>Accessoires</strong>.</p>
<h3 id="smbus">SMBus</h3>
<p>Il est préférable d&rsquo;installer en plus la gestion des accès du bus SMB, en installant
le paquet <code>i2c-tools</code> : <code>apt install i2c-tools</code>.</p>
<p>Ensuite, il faut charger les modules correspondants :</p>
<ul>
<li><strong>i2c-dev</strong> : <code>sudo modprobe i2c-dev</code></li>
<li>Si AMD : <code>sudo modprobe i2c-piix4</code></li>
<li>Si Intel : <code>sudo modprobe i2c-i801</code></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Certaines carte-mères Gigabyte, Aorus ont un conflit ACPI avec leur controleur
SMB ; il est recommandé d&rsquo;ajouter le paramètre suivant <code>acpi_enforce_resources=lax</code>
au kernel. <br>
<em>Voir ci-dessous comment faire…</em></div>

<h2 id="configuration">Configuration</h2>
<p>Les fichiers de configuration s&rsquo;enregistrent dans le répertoire personnel,
généralement sous <code>~/.config/OpenRGB</code> où se trouvent les plugins installés,
ainsi que les logs.</p>
<h3 id="périphériques">Périphériques</h3>
<p>Vos périphériques, s&rsquo;ils sont supportés, seront affichés dans le premier menu
bien nommé <strong>Périphériques</strong>.</p>
<p>Il est possible d&rsquo;activer ou non le support de périphériques dans l&rsquo;onglet
<strong>Périphériques supportés</strong> du menu <strong>Paramètres</strong>.</p>
<h3 id="régionalisation">Régionalisation</h3>
<p>⇒ Menu <strong>Paramètres</strong> &gt; onglets <strong>Paramètres généraux</strong>, la gestion de la langue
est le premier choix possible.</p>
<h3 id="plugins">Plugins</h3>
<p>Les plugins sont des extensions du projet ; une fois téléchargés, il faut en
premier les décompresser.</p>
<p>Le plus simple est d&rsquo;ouvrir l&rsquo;onglet &lsquo;Plugins&rsquo; accessible depuis le menu <strong>Paramètres</strong>.
puis de cliquer sur le bouton [ Installer un plugin ]. <br>
Ils seront enregistrés dans le répertoire personnel <code>~/.config/OpenRGB/plugins</code>.</p>
<p>Il semble qu&rsquo;à chaque ajout est créé un nouveau menu afin de paramètrer le plugin
correspondant.</p>
<h3 id="accès-smbus-automatique">Accès SMBus automatique</h3>
<p>Pour charger les modules SMBus automatiquement au démarrage de votre machine,
il faut créer un fichier <code>/etc/modules-load.d/i2c.conf</code> et y ajouter les noms
des modules nécessaires, tel que, pour l&rsquo;exemple :</p>
<p>⇒ Exemple pour une carte-mère AMD :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">i2c-dev</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">i2c-piix4</span>
</span></span></code></pre></div><p>⇒ Exemple pour une carte-mère Intel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">i2c-dev</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">i2c-i801</span>
</span></span></code></pre></div><p>Ensuite, préférez redémarrer la machine.</p>
<hr>
<h4 id="paramètre-kernel">Paramètre kernel</h4>
<p>Si et seulement si nécessaire, voici comment ajouter un paramètre au noyau pour
qu&rsquo;il soit actif au démarrage de la machine :</p>
<ul>
<li>Avec des droits administrateurs, éditez le fichier <code>/etc/default/grub</code></li>
<li>Se positionner sur la ligne <strong>GRUB_CMDLINE_LINUX_DEFAULT</strong> et ajouter le paramètre
nécessaire à l&rsquo;intérieur des doubles quotes <code>&quot;&quot;</code> <em>(si nécessaire, ajouter
un espace)</em>.</li>
<li>Après avoir sauvegardé, exécuter la commande <code>update-grub</code> <em>toujours avec les
droits admin</em>.</li>
<li>Redémarrer la machine</li>
</ul>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Liste des matériels + ou - supportés : <a href="https://openrgb.org/devices.html" rel="external">https://openrgb.org/devices.html</a></li>
<li>Liste des plugins : <a href="https://openrgb.org/plugins.html" rel="external">https://openrgb.org/plugins.html</a></li>
<li>Gestion des accès :
<ul>
<li><a href="https://gitlab.com/CalcProgrammer1/OpenRGB/-/blob/master/Documentation/SMBusAccess.md" rel="external">SMBus</a></li>
<li><a href="https://gitlab.com/CalcProgrammer1/OpenRGB/-/blob/master/Documentation/USBAccess.md" rel="external">USB</a></li>
</ul>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Découverte du Projet Open Source OpenRGB de gestion des matériels RGB.]]></summary>
        <published>2025-08-31T14:49:50+02:00</published>
        <updated>2025-08-31T16:29:58+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3bbb7ad7-e17d-f148-b75b-200bcd79ea63</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/gnome-fr/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Gnome en français, svp !</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Gnome" scheme="http://doc.huc.fr.eu.org/fr/tags/gnome/" />
        <category term="FR" scheme="http://doc.huc.fr.eu.org/fr/tags/fr/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Avoir sa session utilisateur Gnome Shell en français semble être le parcours du
combattant !</p>
<p>Malheureusement, en 2025, il ne suffit toujours pas de configurer dans les paramètres
systèmes, le format et la langue en <code>Français (France)</code> (dans mon cas) pour que
la session utilisateur soit régionalisée en français ! <br>
L&rsquo;interface reste en anglais.</p>
<p>Sincèrement, c&rsquo;est abérrant :(</p>
<hr>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ locale
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LANG</span><span style="color:#5bc4bf">=</span>fr_FR.UTF-8
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LANGUAGE</span><span style="color:#5bc4bf">=</span>fr_FR
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_CTYPE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_NUMERIC</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_TIME</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_COLLATE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_MONETARY</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_PAPER</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_NAME</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_ADDRESS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_TELEPHONE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_MEASUREMENT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_IDENTIFICATION</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LC_ALL</span><span style="color:#5bc4bf">=</span>C
</span></span></code></pre></div><h2 id="configuration">Configuration</h2>
<p>Pour rappel, voici la signification des variables d&rsquo;environnements liés à la
gestion locale de la langue :</p>
<ul>
<li><code>LANG</code> détermine la langue locale par défaut en absence de toute autre définition
de variables d&rsquo;environnements</li>
<li><code>LANGUAGE</code> traduit les messages dans la langue locale désirée</li>
<li><code>LC_ADDRESS</code> est une convention pour le formatage d&rsquo;adresses postales</li>
<li><code>LC_ALL</code> surcharge toutes les variables d&rsquo;environnements locales, à l&rsquo;exception
de <code>LANGUAGE</code>.</li>
<li><code>LC_COLLATE</code> définit l&rsquo;ordre de classement selon la langue désirée</li>
<li><code>LC_CTYPE</code> classifie la gestion des caractères et la conversion de la casse
de police, selon la langue locale désirée</li>
<li><code>LC_MONETARY</code> formate les informations monétaires</li>
<li><code>LC_MEASUREMENT</code> définit le système de mesure par défaut utilisé dans la région
concernée</li>
<li><code>LC_MESSAGES</code> formate les messages et les réponses systèmes selon la langue
concernée</li>
<li><code>LC_NUMERIC</code> formate l&rsquo;affichage numérique</li>
<li><code>LC_PAPER</code> modifie le taille d&rsquo;(une feuille de) papier selon la région utilisée</li>
<li><code>LC_RESPONSE</code> détermine comment les réponses (par exemple, <code>Oui</code>, <code>Non</code>) apparaissent
à l&rsquo;écran</li>
<li><code>LC_TELEPHONE</code> est utilisée pour la représentation des numéros de téléphone</li>
<li><code>LC_TIME</code> formate le temps et les dates, ainsi que le comportement par défaut
du premier jour de semaine dans les calendriers.</li>
</ul>
<hr>
<h3 id="dpkg-reconfigure-locales">dpkg-reconfigure locales</h3>
<p>L&rsquo;utilisation de la langue locale peut être normalement changée, en tant qu&rsquo;administrateur
système, par le biais de la commande <code>dpkg-reconfigure locales</code> qui permet de
sélectionner celles désirées, ainsi que celle par défaut.</p>
<h4 id="ssh">SSH</h4>
<p>Concernant les utilisateurs systèmes par SSH, il semble recommandé de choisir
aucune langue par défaut.</p>
<h3 id="dmrc">.dmrc</h3>
<p>Vérifiez dans le fichier personnel <code>.dmrc</code> que la variable d&rsquo;environnement
<code>Language</code> corresponde bien au français, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[Desktop]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Session</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">gnome</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Language</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">fr_FR.UTF-8</span>
</span></span></code></pre></div><p>Ce paramétrage influt sur l&rsquo;écran de démarrage GDM, seulement, et peut normalement
être modifié depuis l&rsquo;écran GDM, en bas à droite de celui-ci.</p>
<h3 id="environment">environment</h3>
<p>Depuis Debian Lenny, il semble recommandé de commenter la variable <code>LANG</code> du
fichier <code>/etc/environment</code> si elle avait été précédemment paramétrée.</p>
<h3 id="locale-gen">locale-gen</h3>
<p>Vérifiez le fichier <code>/etc/locale-gen</code> !</p>
<p>Si vous effectuez un changement en commentant ou décommentant une langue, exécutez
avec des droits administrateurs la commande <code>locale-gen</code>.</p>
<h3 id="profile">.profile</h3>
<p>Une astuce est de paramètrer, dans le fichier personnel <code>.profile</code>, la variable
d&rsquo;environnement <code>LANG</code> tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">export LANG</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">fr_FR.UTF-8</span>
</span></span></code></pre></div><h2 id="fin">Fin</h2>
<ul>
<li>
<p>Si les nouveaux paramétrages n&rsquo;ont été fait qu&rsquo;en session utilisateur, sortir
de la session pour la redémarrer…</p>
</li>
<li>
<p>Si l&rsquo;usage des droits administrateurs a été nécessaire, redémarrez la machine.</p>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>Astuce <code>.profile</code> : <a href="https://tssr.eklablog.fr/mettre-gnome-en-francais-a215686845" rel="external">https://tssr.eklablog.fr/mettre-gnome-en-francais-a215686845</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Avoir une session utilisateur en français avec Gnome Shell sous Debian.]]></summary>
        <published>2025-08-05T12:14:59+02:00</published>
        <updated>2025-08-07T17:50:42+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8805fe1d-f748-b956-cc20-7c4a467b9fc6</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/qemu-bridge-network/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Pont réseau pour QEMU</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="QEMU" scheme="http://doc.huc.fr.eu.org/fr/tags/qemu/" />
        <category term="Bridge" scheme="http://doc.huc.fr.eu.org/fr/tags/bridge/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Comment créer un pont réseau logiciel sous Debian, pour faciliter les
communications réseaux avec les machines virtuelles, gérées par QEMU.</p>
<p>La machine hôte et la|les VM invitées sont sur le même segment réseau.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Les interfaces réseaux Ethernet de type Wifi ne peuvent pas être utilisées
pour créer un pont réseau logiciel ; il faut impérativement utiliser
un périphérique réseau Ethernet filaire.</div>

<h2 id="installation">Installation</h2>
<p>Le premier point est d&rsquo;installer les outils nécessaires au pont réseau
logiciel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install bridge-utils
</span></span></code></pre></div><h2 id="configuration">Configuration</h2>
<p>Cet article propose la configuration soit en mode CLI, soit par le biais
de l&rsquo;interface graphique de Network Manager.</p>
<p><strong>Choisissez l&rsquo;un ou l&rsquo;autre, pas les deux !</strong></p>
<h3 id="cli">CLI</h3>
<p>Pour le principe, voici comment configurer le pont en mode CLI :</p>
<ul>
<li>Pour connaître le nom de votre interface réseau Ethernet filaire :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: ip a
</span></span><span style="display:flex;"><span>1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">65536</span> qdisc noqueue state UNKNOWN group default qlen <span style="color:#f99b15">1000</span>
</span></span><span style="display:flex;"><span>    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
</span></span><span style="display:flex;"><span>    inet 127.0.0.1/8 scope host lo
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span><span style="display:flex;"><span>    inet6 ::1/128 scope host noprefixroute
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span><span style="display:flex;"><span>2: enp0s31f6: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">1500</span> qdisc pfifo_fast state UP group default qlen <span style="color:#f99b15">1000</span>
</span></span><span style="display:flex;"><span>    inet 192.168.***.***/24 brd 192.168.***.255 scope global enp0s31f6
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span></code></pre></div><p>Dans mon cas, l&rsquo;interface filaire 2 en question se nomme <code>enp0s31f6</code>… adaptez à votre cas !</p>
<ul>
<li>Création du pont :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo brctl addbr br0
</span></span></code></pre></div><ul>
<li>ajout de l&rsquo;interface réseau :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo brctl addif br0 enp0s31f6
</span></span></code></pre></div><ul>
<li>configurez le pont dans un fichier dédié, nommé pour l&rsquo;exemple,
<code>/etc/network/interfaces.d/br0</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">## DHCP ip config file for br0 ##</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auto br0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Bridge setup</span>
</span></span><span style="display:flex;"><span> <span style="color:#06b6ef">iface br0 inet dhcp</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">bridge_ports enp0s31f6</span>
</span></span></code></pre></div><p><em>Si vous préférez avoir une adresse IP statique sur le même segment réseau
que votre machine hôte, adaptez en utilisant <code>static</code> au lieu de <code>dhcp</code>
et en modifiant selon votre besoin.</em></p>
<ul>
<li>Vérifiez quand même que la configuration par défaut des interfaces réseaux :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: cat /etc/network/interfaces
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># This file describes the network interfaces available on your system</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># and how to activate them. For more information, see interfaces(5).</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">source /etc/network/interfaces.d/*</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># The loopback network interface</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auto lo</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">iface lo inet loopback</span>
</span></span></code></pre></div><p>Si ce n&rsquo;est pas le cas, adaptez ! <em>(cela signifie que vous avez déjà modifié votre fichier)</em></p>
<p>Votre pont logiciel <strong>br0</strong> est créé et devrait être fonctionnel.</p>
<h3 id="network-manager-gui">Network Manager GUI</h3>
<p>Ce qui suit configure le pont réseau depuis l&rsquo;interface graphique de
Network Manager.</p>
<p>L&rsquo;interface graphique de Network Manager est utilisable depuis l&rsquo;applet
réseau de votre bureau, soit en ligne de commande grâce à :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo nm-connection-editor
</span></span></code></pre></div><hr>
<ol>
<li>Cliquez sur le bouton [ + ] pour ajouter une nouvelle connection</li>
<li>Sélectionnez dans la catégorie <strong>Virtuel</strong>, le choix <strong>Pont</strong>

    
                <figure role="figure" aria-label="Network Manager : ajout d’un pont">
    <a href="/images/debian/nm-connection-1.1-ajout-pont.png" title="Network Manager : ajout d’un pont">
        <picture>
            <source srcset="/images/debian/nm-connection-1.1-ajout-pont.png.avif" type="image/avif"><source srcset="/images/debian/nm-connection-1.1-ajout-pont_hu_6a9a07fae549af5b.webp" type="image/webp">
            <img alt="Network Manager : ajout d’un pont" height="209" id="img_images_debian_nm-connection-1.1-ajout-pont.png_0" loading="lazy" src="/images/debian/nm-connection-1.1-ajout-pont.png" type="image/png" width="300">
        </picture>
    </a>
    <figcaption>Network Manager : ajout d’un pont</figcaption>
</figure></li>
<li>Nommez la connexion, telle que <strong>br0</strong>, ainsi que l&rsquo;interface dans
l&rsquo;onglet &lsquo;Pont&rsquo; <em>(ouvert par défaut)</em>

    
                <figure role="figure" aria-label="Network Manager : nommer nouvelle connection">
    <a href="/images/debian/nm-connection-2.br0.png" title="Network Manager : nommer nouvelle connection">
        <picture>
            <source srcset="/images/debian/nm-connection-2.br0.png.avif" type="image/avif"><source srcset="/images/debian/nm-connection-2.br0_hu_f70162d8e90753e4.webp" type="image/webp">
            <img alt="Network Manager : nommer nouvelle connection" height="353" id="img_images_debian_nm-connection-2.br0.png_1" loading="lazy" src="/images/debian/nm-connection-2.br0.png" type="image/png" width="300">
        </picture>
    </a>
    <figcaption>Network Manager : nommer nouvelle connection</figcaption>
</figure></li>
</ol>
<ul>
<li>Cliquez sur le bouton [ Ajouter ] pour ajouter un nouveau type de connexion</li>
<li>Laissez le choix par défaut <strong>Ethernet</strong> puis cliquez sur le bouton [ Créer… ]
<ul>
<li>Dans l&rsquo;onglet &lsquo;Ethernet&rsquo; <em>(ouvert par défaut)</em>, à &lsquo;Périphérique&rsquo;,
choisissez le périphérique réseau de type Ethernet avec lequel
vous souhaitez fonctionner</li>
<li>Cliquez sur le bouton [ Enregistrer ]

    
                <figure role="figure" aria-label="Network Manager : ajout d’une connection Ethernet">
    <a href="/images/debian/nm-connection-3.Ethernet.png" title="Network Manager : ajout d’une connection Ethernet">
        <picture>
            <source srcset="/images/debian/nm-connection-3.Ethernet.png.avif" type="image/avif"><source srcset="/images/debian/nm-connection-3.Ethernet_hu_7005b9ee350295e7.webp" type="image/webp">
            <img alt="Network Manager : ajout d’une connection Ethernet" height="249" id="img_images_debian_nm-connection-3.Ethernet.png_2" loading="lazy" src="/images/debian/nm-connection-3.Ethernet.png" type="image/png" width="300">
        </picture>
    </a>
    <figcaption>Network Manager : ajout d’une connection Ethernet</figcaption>
</figure></li>
</ul>
</li>
<li>Vérifiez dans les onglets &lsquo;Paramètres IPv4&rsquo; et &lsquo;Paramètres IPv6&rsquo;, que
les méthodes soient de types <strong>Automatique</strong> - <em>bien sûr ceci
est valable si sur votre réseau, vous avez un serveur DHCP ; autrement
en choisissant selon votre cas, par exemple si vous préférez un
adresse IP statique, en paramétrant sur &lsquo;Manuel&rsquo;, etc…</em></li>
<li>Une fois terminé, clique sur le bouton [ Enregistrer ]

    
                <figure role="figure" aria-label="Network Manager : ajout d’un pont">
    <a href="/images/debian/nm-connection-exemple-pont-ethernet.png" title="Network Manager : ajout d’un pont">
        <picture>
            <source srcset="/images/debian/nm-connection-exemple-pont-ethernet.png.avif" type="image/avif"><source srcset="/images/debian/nm-connection-exemple-pont-ethernet_hu_1ce8ab11271839b2.webp" type="image/webp">
            <img alt="Network Manager : ajout d’un pont" height="213" id="img_images_debian_nm-connection-exemple-pont-ethernet.png_3" loading="lazy" src="/images/debian/nm-connection-exemple-pont-ethernet.png" type="image/png" width="300">
        </picture>
    </a>
    <figcaption>Network Manager : ajout d’un pont</figcaption>
</figure></li>
</ul>
<p>Votre pont réseau logiciel est créé !</p>
<hr>
<h3 id="qemu">QEMU</h3>
<p>Hormis le fait d&rsquo;installer QEMU sur votre machine hôte, il est nécessaire
d&rsquo;installer les bibliothèques <strong>libvirt</strong> ; celles-ci s&rsquo;installent en
dépendance du paquet <strong>virt-manager</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install libosinfo-bin qemu-system virt-manager
</span></span></code></pre></div><p>Si vous voulez gérer <strong>virt-manager</strong> avec vos droits utilisateurs, il faut
ajouter votre identifiant aux groupes <code>libvirt</code> et <code>libvirt-qemu</code>.</p>
<h4 id="virt-manager">virt-manager</h4>
<p>Lors de la création de votre machine virtuelle, dans les détails de l&rsquo;interface
réseau, il faut paramètrer selon votre propre pont réseau, tel que pour
reprendre le propos d&rsquo;un pont nommé &lsquo;br0&rsquo; :</p>
<ol>
<li>Source du réseau : <strong>bridge device…</strong>
<ul>
<li>Device name : <strong>br0</strong></li>
</ul>
</li>
<li>Modèle du périphérique : soit <strong>virtio</strong>, soit <strong>e1000e</strong>
<em>(de dernier émule un périphérique de marque Intel de qualité réseau indéniable)</em>
<ul>
<li>État du lien : veillez à ce que la case à cocher <strong>[ ] actif</strong>, le soit.</li>
</ul>
</li>
</ol>
<p>Pour l&rsquo;exemple :

    
                <figure role="figure" aria-label="virt-manager : exemple d’interface réseau paramétrée sur le pont ‘br0’">
    <a href="/images/debian/virt-manager-interface-exemple.png" title="virt-manager : exemple d’interface réseau paramétrée sur le pont ‘br0’">
        <picture>
            <source srcset="/images/debian/virt-manager-interface-exemple.png.avif" type="image/avif"><source srcset="/images/debian/virt-manager-interface-exemple_hu_f28d5ba008115905.webp" type="image/webp">
            <img alt="virt-manager : exemple d’interface réseau paramétrée sur le pont ‘br0’" height="108" id="img_images_debian_virt-manager-interface-exemple.png_4" loading="lazy" src="/images/debian/virt-manager-interface-exemple.png" type="image/png" width="300">
        </picture>
    </a>
    <figcaption>virt-manager : exemple d’interface réseau paramétrée sur le pont ‘br0’</figcaption>
</figure></p>
<hr>
<p>L&rsquo;édition de votre machine virtuelle peut se faire en mode CLI, aussi,
en appelant l&rsquo;outil <code>virsh</code>, tel que pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: virsh --connect qemu:///system edit nom-votre-vm
</span></span></code></pre></div><p>ce qui vous donnera accès à son fichier XML où vous pourrez entre autre
modifier la section <code>interface</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>(…)
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;interface</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#39;bridge&#39;</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;mac</span> <span style="color:#06b6ef">address=</span><span style="color:#48b685">&#39;00:00:00:ad:a1:9f&#39;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;source</span> <span style="color:#06b6ef">bridge=</span><span style="color:#48b685">&#39;br0&#39;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;model</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#39;e1000e&#39;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;address</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#39;pci&#39;</span> <span style="color:#06b6ef">domain=</span><span style="color:#48b685">&#39;0x0000&#39;</span> <span style="color:#06b6ef">bus=</span><span style="color:#48b685">&#39;0x01&#39;</span> <span style="color:#06b6ef">slot=</span><span style="color:#48b685">&#39;0x00&#39;</span> <span style="color:#06b6ef">function=</span><span style="color:#48b685">&#39;0x0&#39;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;/interface&gt;</span>
</span></span><span style="display:flex;"><span>(…)
</span></span></code></pre></div><hr>
<h4 id="virt-install">virt-install</h4>
<p>Si jamais vous créez votre VM avec l&rsquo;outil <code>virt-install</code>, utilisez le
paramètre <code>network</code> pour spécifier l&rsquo;utilisation du pont <strong>br0</strong>,
tel que pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: vir-install … --network <span style="color:#ef6155">bridge</span><span style="color:#5bc4bf">=</span>br0,model.type<span style="color:#5bc4bf">=</span>e1000,type<span style="color:#5bc4bf">=</span>bridge …
</span></span></code></pre></div><h2 id="vérifications">Vérifications</h2>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Pensez à redémarrer soit la machine hôte, soit à redémarrer la couche réseau</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo systemctl restart NetworkManager
</span></span></code></pre></div></div>

<hr>
<p>⇒ Vérifions avec l&rsquo;outil contrôleur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: brctl show
</span></span><span style="display:flex;"><span>bridge name bridge id       STP enabled interfaces
</span></span><span style="display:flex;"><span>br0     8000.2ef40298a3d6   yes     enp0s31f6
</span></span></code></pre></div><p>On a bien un pont nommé <code>br0</code> avec pour interface ethernet <code>enp0s31f6</code>,
comme le montre la capture écran de l&rsquo;interface graphique ci-dessus.</p>
<p>⇒ puis par vérifier avec l&rsquo;outil <code>bridge</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: bridge link
</span></span><span style="display:flex;"><span>2: enp0s31f6: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">1500</span> master br0 state forwarding priority <span style="color:#f99b15">32</span> cost <span style="color:#f99b15">100</span>
</span></span></code></pre></div><p>⇒ continuons avec l&rsquo;outil <code>ip</code> pour vérifier les différentes interfaces réseaux :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: ip a s
</span></span><span style="display:flex;"><span>1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">65536</span> qdisc noqueue state UNKNOWN group default qlen <span style="color:#f99b15">1000</span>
</span></span><span style="display:flex;"><span>    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
</span></span><span style="display:flex;"><span>    inet 127.0.0.1/8 scope host lo
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span><span style="display:flex;"><span>    inet6 ::1/128 scope host noprefixroute
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span><span style="display:flex;"><span>2: enp0s31f6: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">1500</span> qdisc fq_codel master br0 state UP group default qlen <span style="color:#f99b15">1000</span>
</span></span><span style="display:flex;"><span>    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
</span></span><span style="display:flex;"><span>3: br0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu <span style="color:#f99b15">1500</span> qdisc noqueue state UP group default qlen <span style="color:#f99b15">1000</span>
</span></span><span style="display:flex;"><span>    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
</span></span><span style="display:flex;"><span>    inet 192.168.***.128/24 brd 192.168.***.255 scope global dynamic noprefixroute br0
</span></span><span style="display:flex;"><span>       valid_lft 36709sec preferred_lft 36709sec
</span></span><span style="display:flex;"><span>    inet6 fe80::****:****:****:****/64 scope link noprefixroute
</span></span><span style="display:flex;"><span>       valid_lft forever preferred_lft forever
</span></span></code></pre></div><ul>
<li>nous avons bien le pont <code>br0</code> en tant qu&rsquo;interface 3</li>
<li>l&rsquo;interface réseau 2 <code>enp0s31f6</code> ayant pour <code>master br0</code>, donc faisant
bien partie du pont <code>br0</code></li>
</ul>
<p>⇒ puis vérifions la route par défaut :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: ip r
</span></span><span style="display:flex;"><span>default via 192.168.***.1 dev br0 proto dhcp src 192.168.***.128 metric <span style="color:#f99b15">425</span>
</span></span><span style="display:flex;"><span>192.168.***.0/24 dev br0 proto kernel scope link src 192.168.***.128 metric <span style="color:#f99b15">425</span>
</span></span></code></pre></div><ul>
<li>la route par défaut est bien celle de ma passerelle passant par le pont…</li>
</ul>
<hr>
<p>Voilà !</p>
<p>Rien de bien compliqué pour créer un pont logiciel réseau pour la communication
de vos VM, sur le même segment réseau que votre machine hôte.</p>
<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pour rappel : <strong>non</strong>, un pont logiciel réseau n&rsquo;est pas une interface de type
NAT ; il n&rsquo;y a pas besoin ni de configurer le système, ni le parefeu pour
transférer (<em>forward</em>) le trafic réseau !</div>

<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Créer un pont réseau logiciel sous Debian, à utiliser avec Qemu]]></summary>
        <published>2024-02-25T16:56:54+01:00</published>
        <updated>2026-03-08T02:41:09+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:81a4d3e8-13e4-9184-7092-8c543b7259e3</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/vm-windows11/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [Debian :: Virtualisation] Windows 11</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="Windows" scheme="http://doc.huc.fr.eu.org/fr/tags/windows/" />
        <category term="QEMU" scheme="http://doc.huc.fr.eu.org/fr/tags/qemu/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Abordons la virtualisation de Windows 11, sous Debian Sid, avec QEMU,
avec pour prérequis nécessaire l&rsquo;utilisation de TPM, Secure-Boot,
partage de données entre la machine hôte et la VM, … sans oublier l&rsquo;UEFI.</p>
<p>Ce processus convient aussi pour un Windows 10 virtualisé nécessitant les
mêmes prérequis.</p>
<h2 id="pré-requis">Pré-requis</h2>
<p>L&rsquo;hôte sera paramétré en tant que pont et la VM fera partie du même réseau
que l&rsquo;hôte.</p>
<p>Je n&rsquo;aborde pas ici la configuration de l&rsquo;hôte en tant que bridge réseau. <br>
<em>Lire mon article : <a href="http://doc.huc.fr.eu.org/fr/sys/debian/qemu-bridge-network/">Debian : Pont réseau pour QEMU</a></em></p>
<h3 id="windows-11">Windows 11</h3>
<p>Le téléchargement de l&rsquo;image ISO de Windows 11 se fait depuis :
<a href="https://www.microsoft.com/software-download/windows11" rel="external">https://www.microsoft.com/software-download/windows11</a></p>
<p>Procurez-vous légalement une clé de licence Windows.</p>
<p>⇒ Les prérequis minimum pour une <a href="https://learn.microsoft.com/fr-fr/windows/whats-new/windows-11-requirements#virtual-machine-support" rel="external">machine virtuelle exécutant Windows</a>
11 sont les suivants :</p>
<ul>
<li>64 Go de stockage</li>
<li>4 Go mémoire</li>
<li>2 CPU virtuels</li>
</ul>
<h3 id="qemu">QEMU</h3>
<p>QEMU doit être installé:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install libosinfo-bin qemu-system virt-manager virtiofsd
</span></span></code></pre></div><ul>
<li><code>libosinfo-bin</code> est un outil pour interroger la base de données osinfo.</li>
<li><code>virt-manager</code> est une application de bureau pour gérer des machines virtuelles.</li>
<li><code>virtiofsd</code> est le service qui montera le système de fichier virtuel.</li>
</ul>
<h3 id="tpm-secure-boot-uefi">TPM, Secure-Boot, UEFI</h3>
<p>Parmi les pré-requis de Windows 11, il y a la gestion :</p>
<ul>
<li>de TPM.</li>
<li>du Secure Boot</li>
<li>et de l&rsquo;UEFI.</li>
</ul>
<p>Il nous installer les binaires suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install ovmf swtpm swtpm-tools
</span></span></code></pre></div><h3 id="client-graphique">Client graphique</h3>
<p>Pour accéder à l&rsquo;interface graphique de la VM, au choix</p>
<ul>
<li>le serveur Spice (par défaut)</li>
<li>ou VNC.</li>
</ul>
<h4 id="spice">Spice</h4>
<p>Par défaut l&rsquo;interface graphique de la VM est configurée sur <strong>spice</strong>.</p>
<p>Il faut installer les paquets <strong>spice-vdagent</strong> et <strong>spice-client-gtk</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install spice-vdagent spice-client-gtk
</span></span></code></pre></div><p>Ce tutoriel se base sur l&rsquo;utilisation de spice.</p>
<h4 id="vnc">VNC</h4>
<p>Pour utiliser l&rsquo;interface graphique avec le serveur VNC, un client comme
<strong>tigervnc-viewer</strong> peut être suffisant.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo apt install tigervnc-viewer
</span></span></code></pre></div><p>Ce tutoriel n&rsquo;aborde pas plus cette utilisation… si ce n&rsquo;est de pararmètrer
le client VNC d&rsquo;interroger localhost et le port VNC par défaut <em>(à moins
que vous l&rsquo;ayez changé, dans ce cas agissez en conséquence)</em>.</p>
<h2 id="création-de-la-vm">Création de la VM</h2>
<h3 id="droits-utilisateur">Droits utilisateur</h3>
<p>Ajoutez votre utilisateur au groupe <strong>libvirt</strong>, voire <strong>libvirt-qemu</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: sudo adduser your-id libvirt
</span></span><span style="display:flex;"><span>$: sudo adduser your-id libvirt-qemu
</span></span></code></pre></div><p>Ensuite, choisissez pour faire l&rsquo;installation de la VM :</p>
<ul>
<li>soit en mode CLI,</li>
<li>soit par l&rsquo;installateur graphique virt-manager</li>
</ul>
<h3 id="virt-install-cli">virt-install CLI</h3>
<p>Partant du principe d&rsquo;un répertoire dédié dans votre homme, nommé <strong>VM</strong> :</p>
<ol>
<li>Création de la VM:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: cd ~/VM
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>pwd<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>Win11Test
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">path</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">.qcow2&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">size</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">64</span>
</span></span><span style="display:flex;"><span>$: qemu-img create -f qcow2 <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">path</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">size</span><span style="color:#f99b15">}</span><span style="color:#48b685">G&#34;</span>
</span></span></code></pre></div><ol start="2">
<li>Démarrage de l&rsquo;installation :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$: <span style="color:#ef6155">isofile</span><span style="color:#5bc4bf">=</span>Win11_23H2_French_x64v2.iso
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">fs_dest</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;C:\\vmshare&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">fs_src</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/vmshare&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">cdrom</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">isofile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">conn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;qemu:///system&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">cpu</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;check=none,mode=host-passthrough,migratable=on&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">disk</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;device=disk,format=qcow2,path=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">path</span><span style="color:#f99b15">}</span><span style="color:#48b685">,size=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">size</span><span style="color:#f99b15">}</span><span style="color:#48b685">,target.bus=sata,target.dev=sda,type=file&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">fs</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;accessmode=passthrough,source=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">fs_src</span><span style="color:#f99b15">}</span><span style="color:#48b685">,target=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">fs_dest</span><span style="color:#f99b15">}</span><span style="color:#48b685">,type=mount,driver.type=virtiofs&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">graphic</span><span style="color:#5bc4bf">=</span>spice
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">machine</span><span style="color:#5bc4bf">=</span>q35
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">mem</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;4096,maxMemory=16384&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">memBacking</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;source.type=memfd,access.mode=shared&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">net</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;bridge=br0,model.type=e1000,type=bridge&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">os</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;detect=on,name=win11&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">tpm</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;emulator,version=2.0&#34;</span>
</span></span><span style="display:flex;"><span>$: <span style="color:#ef6155">vcpu</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;2,maxvcpus=4&#34;</span>
</span></span><span style="display:flex;"><span>$: virt-install --accelerate --cdrom <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cdrom</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --connect <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">conn</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --cpu <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cpu</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --disk <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">disk</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --filesystem <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">fs</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --graphics <span style="color:#ef6155">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">graphic</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --hvm --machine <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">machine</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --memory <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">mem</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --memorybacking<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">memBacking</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --name <span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span> --network <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">net</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --os-variant <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">os</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --tpm <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tpm</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --vcpus <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">vcpu</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><p>Direction vers l&rsquo;interface graphique de la nouvelle fenêtre qui vient de
s&rsquo;ouvrir, titrée &ldquo;Win11Test&rdquo;, assez rapidement pour pouvoir valider le
choix de démarrer sur le CD-ROM.</p>
<p>Selon votre puissance machine hôte, l&rsquo;installation de Windows se fait en
quelques minutes…</p>
<hr>
<h3 id="gestionnaire-graphique-virt-manager">Gestionnaire graphique virt-manager</h3>
<ul>
<li>
<p>Veillez à activer l&rsquo;option d&rsquo;architecture en spécifiant l&rsquo;*<em>Architecture</em> : <strong>x86_64</strong> :

                <figure role="figure" aria-label="virt-manager : création de la nouvelle VM">
    <a href="/images/debian/qemu/virt-manager-1.creation.png" title="virt-manager : création de la nouvelle VM">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-1.creation.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-1.creation_hu_58a22f068deb1d96.webp" type="image/webp">
            <img alt="virt-manager : création de la nouvelle VM" height="536" id="img_images_debian_qemu_virt-manager-1.creation.png_0" loading="lazy" src="/images/debian/qemu/virt-manager-1.creation.png" type="image/png" width="509">
        </picture>
    </a>
    <figcaption>virt-manager : création de la nouvelle VM</figcaption>
</figure></p>
</li>
<li>
<p>Choisir le chemin de l&rsquo;ISO d&rsquo;installation de Windows :

                <figure role="figure" aria-label="virt-manager : choisir le média d’installation">
    <a href="/images/debian/qemu/virt-manager-2.media-installation.png" title="virt-manager : choisir le média d’installation">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-2.media-installation.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-2.media-installation_hu_d06c0ea26e03d10a.webp" type="image/webp">
            <img alt="virt-manager : choisir le média d’installation" height="543" id="img_images_debian_qemu_virt-manager-2.media-installation.png_1" loading="lazy" src="/images/debian/qemu/virt-manager-2.media-installation.png" type="image/png" width="602">
        </picture>
    </a>
    <figcaption>virt-manager : choisir le média d’installation</figcaption>
</figure></p>
</li>
<li>
<p>Choisir les paramètres mémoire et CPU :

                <figure role="figure" aria-label="virt-manager : choisir les paramètres mémoire et CPU">
    <a href="/images/debian/qemu/virt-manager-3.parametres-mem-cpu.png" title="virt-manager : choisir les paramètres mémoire et CPU">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-3.parametres-mem-cpu.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-3.parametres-mem-cpu_hu_326415fbe9c41fc6.webp" type="image/webp">
            <img alt="virt-manager : choisir les paramètres mémoire et CPU" height="536" id="img_images_debian_qemu_virt-manager-3.parametres-mem-cpu.png_2" loading="lazy" src="/images/debian/qemu/virt-manager-3.parametres-mem-cpu.png" type="image/png" width="507">
        </picture>
    </a>
    <figcaption>virt-manager : choisir les paramètres mémoire et CPU</figcaption>
</figure></p>
</li>
<li>
<p>Activer le stockage en sélectionnant un personnalisé :

                <figure role="figure" aria-label="virt-manager : activer le stockage personnalisé">
    <a href="/images/debian/qemu/virt-manager-4.0.stockage.png" title="virt-manager : activer le stockage personnalisé">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-4.0.stockage.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-4.0.stockage_hu_2414f2c57d3b1f2.webp" type="image/webp">
            <img alt="virt-manager : activer le stockage personnalisé" height="535" id="img_images_debian_qemu_virt-manager-4.0.stockage.png_3" loading="lazy" src="/images/debian/qemu/virt-manager-4.0.stockage.png" type="image/png" width="513">
        </picture>
    </a>
    <figcaption>virt-manager : activer le stockage personnalisé</figcaption>
</figure></p>
</li>
<li>
<p>Dans votre home, créez un volume de stockage personnalisé

                <figure role="figure" aria-label="virt-manager : créer un volume de stockage">
    <a href="/images/debian/qemu/virt-manager-4.1.stockage-creation.png" title="virt-manager : créer un volume de stockage">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-4.1.stockage-creation.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-4.1.stockage-creation_hu_881a9a735b29b0dc.webp" type="image/webp">
            <img alt="virt-manager : créer un volume de stockage" height="628" id="img_images_debian_qemu_virt-manager-4.1.stockage-creation.png_4" loading="lazy" src="/images/debian/qemu/virt-manager-4.1.stockage-creation.png" type="image/png" width="794">
        </picture>
    </a>
    <figcaption>virt-manager : créer un volume de stockage</figcaption>
</figure></p>
</li>
</ul>
<p>
                <figure role="figure" aria-label="virt-manager : créer du volume de stockage">
    <a href="/images/debian/qemu/virt-manager-4.2.stockage-creation.png" title="virt-manager : créer du volume de stockage">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-4.2.stockage-creation.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-4.2.stockage-creation_hu_bdf50985d64764a5.webp" type="image/webp">
            <img alt="virt-manager : créer du volume de stockage" height="645" id="img_images_debian_qemu_virt-manager-4.2.stockage-creation.png_5" loading="lazy" src="/images/debian/qemu/virt-manager-4.2.stockage-creation.png" type="image/png" width="764">
        </picture>
    </a>
    <figcaption>virt-manager : créer du volume de stockage</figcaption>
</figure></p>
<p>
                <figure role="figure" aria-label="virt-manager : localiser le stockage personnalisé">
    <a href="/images/debian/qemu/virt-manager-4.3.stockage-choix-volume.png" title="virt-manager : localiser le stockage personnalisé">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-4.3.stockage-choix-volume.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-4.3.stockage-choix-volume_hu_b40d418a4602295e.webp" type="image/webp">
            <img alt="virt-manager : localiser le stockage personnalisé" height="534" id="img_images_debian_qemu_virt-manager-4.3.stockage-choix-volume.png_6" loading="lazy" src="/images/debian/qemu/virt-manager-4.3.stockage-choix-volume.png" type="image/png" width="758">
        </picture>
    </a>
    <figcaption>virt-manager : localiser le stockage personnalisé</figcaption>
</figure></p>
<p>
                <figure role="figure" aria-label="virt-manager : gérer le stockage personnalisé">
    <a href="/images/debian/qemu/virt-manager-4.4.stockage-personnalise.png" title="virt-manager : gérer le stockage personnalisé">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-4.4.stockage-personnalise.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-4.4.stockage-personnalise_hu_6620676cd26905da.webp" type="image/webp">
            <img alt="virt-manager : gérer le stockage personnalisé" height="537" id="img_images_debian_qemu_virt-manager-4.4.stockage-personnalise.png_7" loading="lazy" src="/images/debian/qemu/virt-manager-4.4.stockage-personnalise.png" type="image/png" width="512">
        </picture>
    </a>
    <figcaption>virt-manager : gérer le stockage personnalisé</figcaption>
</figure></p>
<ul>
<li>Commençons l&rsquo;installation de la VM
<ul>
<li>Veillez à sélectionner le type de réseau, en tant que <strong>Bridge device</strong></li>
<li>et à lui donner le nom correct de votre pont, dans le champ <strong>Device name</strong>

                <figure role="figure" aria-label="virt-manager : activer le stockage">
    <a href="/images/debian/qemu/virt-manager-5.start-install.png" title="virt-manager : activer le stockage">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-5.start-install.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-5.start-install_hu_43fe3cbbb8b94c85.webp" type="image/webp">
            <img alt="virt-manager : activer le stockage" height="535" id="img_images_debian_qemu_virt-manager-5.start-install.png_8" loading="lazy" src="/images/debian/qemu/virt-manager-5.start-install.png" type="image/png" width="510">
        </picture>
    </a>
    <figcaption>virt-manager : activer le stockage</figcaption>
</figure></li>
</ul>
</li>
</ul>
<hr>
<p>Le reste est le processus d&rsquo;installation de Windows…</p>
<h2 id="installation-de-windows">Installation de Windows</h2>
<p>Je ne développe pas le processus d&rsquo;installation en lui-même ; il ne différe
en rien d&rsquo;une installation sur une machine physique.</p>
<h2 id="partage">Partage</h2>
<p>Le moyen le plus simple actuellement pour partager des copier-coller,
des fichiers entre l&rsquo;hôte et l&rsquo;invité est l&rsquo;utilisation du serveur <strong>spice</strong> ;
l&rsquo;utilisation de VNC n&rsquo;est pas compatible pour ce propos.</p>
<p>D&rsquo;autres possibilités sont l&rsquo;usage de SSHFS, voire Samba, qui ne seront
pas abordés dans cet article.</p>
<hr>
<p>⇒ Sur l&rsquo;hôte :</p>
<pre tabindex="0"><code class="language-dash" data-lang="dash">$: sudo apt install qemu-guest-agent spice-vdagent
</code></pre><p>⇒ Dans la VM :</p>
<p>Une fois l&rsquo;installation de Windows terminée, et dans votre session utilisateur,
avec n&rsquo;importe quel navigateur web, allez télécharger :</p>
<ul>
<li>
<p>l&rsquo;utilitaire <strong>WinFSP</strong> : <a href="https://winfsp.dev/rel/" rel="external">https://winfsp.dev/rel/</a> <br>
C&rsquo;est l&rsquo;équivalent de <strong>Fuse</strong> pour Windows.</p>
<ul>
<li>Veillez à l&rsquo;installation du <strong>Core</strong> - <em>ce qui est normalement proposé par défaut</em> <br>
(voir ci-dessous : <a href="/fr/sys/debian/vm-windows11/#winfsp">WinFSP</a>)</li>
</ul>
</li>
<li>
<p>les outils <strong>VirtIO</strong> : <br>
<a href="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win-guest-tools.exe" rel="external">https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win-guest-tools.exe</a> <br>
Cet ensemble packagé par l&rsquo;équipe Fedora comprend les pilotes logiciels
nécessaires à la paravirtualisation et l&rsquo;émulation matérielle ; il
embarque aussi l&rsquo;agent Spice pour la gestion de l&rsquo;affichage graphique,
et son redimensionnement automatique, le copier-coller entre l&rsquo;hôte
et la VM, la redirection des périphériques USB vers la VM.</p>
<ul>
<li>Veillez à l&rsquo;installation de <strong>Viofs</strong> <br>
(voir ci-dessous : <a href="/fr/sys/debian/vm-windows11/#virtio">VirtIO</a>)</li>
</ul>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">L&rsquo;installation de WinFSP doit se faire avant celle de VirtioFS, autrement
le service ad hoc refusera de démarrer.</div>

<h3 id="virt-install">virt-install</h3>
<p>Lors de l&rsquo;installation par le biais de l&rsquo;outil <strong>virt-install</strong> en CLI,
normalement vous avez paramétré :</p>
<ul>
<li>les variables <code>fs_dest</code> et <code>fs_src</code> nécessaires pour paramétrer correctement
la variable <code>--filesystem</code></li>
<li>ainsi que la variable <code>memoryBacking</code> qui est nécessaire pour le partage
mémoire.</li>
</ul>
<h3 id="virt-manager">virt-manager</h3>
<p>Si vous avez fait l&rsquo;installation de la VM par le biais de virt-manager,
arrêtez proprement la VM, puis paramétrez le partage de fichier.</p>
<ol>
<li>Affichez les détails de la VM</li>
<li>Cliquez sur <strong>Mémoire</strong> pour activer l&rsquo;option <strong>Enable shared memory</strong>

                <figure role="figure" aria-label="virt-manager : activer la mémoire partagée">
    <a href="/images/debian/qemu/virt-manager-6.0.partage-memoire.png" title="virt-manager : activer la mémoire partagée">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-6.0.partage-memoire.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-6.0.partage-memoire_hu_84f717ccd2ba14c4.webp" type="image/webp">
            <img alt="virt-manager : activer la mémoire partagée" height="309" id="img_images_debian_qemu_virt-manager-6.0.partage-memoire.png_9" loading="lazy" src="/images/debian/qemu/virt-manager-6.0.partage-memoire.png" type="image/png" width="702">
        </picture>
    </a>
    <figcaption>virt-manager : activer la mémoire partagée</figcaption>
</figure></li>
<li>Puis cliquez sur le bouton [ Ajouter un matériel ], <em>en bas à gauche de la +
fenêtre des détails</em>…</li>
<li>Sélectionnez le choix <strong>Système de fichiers</strong> et paramétrez :
<ul>
<li>Pilote : <strong>virtiofs</strong></li>
<li>Chemin de la source : Parcourez vers votre répertoire de partage sur
votre hôte, tel que <code>~/VM/vmshare</code></li>
<li>chemin de la cible : <code>C:\vmshare</code></li>
<li><em>vous pouvez choisir d&rsquo;exporter les fichiers en lecture seule, en cliquant
sur la case à cocher adéquate.</em></li>
<li>cliquez sur le bouton [ Terminer ]

                <figure role="figure" aria-label="virt-manager : activer le système de fichiers">
    <a href="/images/debian/qemu/virt-manager-6.1.Systeme-fichiers.png" title="virt-manager : activer le système de fichiers">
        <picture>
            <source srcset="/images/debian/qemu/virt-manager-6.1.Systeme-fichiers.png.avif" type="image/avif"><source srcset="/images/debian/qemu/virt-manager-6.1.Systeme-fichiers_hu_cd6d05ca6928196d.webp" type="image/webp">
            <img alt="virt-manager : activer le système de fichiers" height="649" id="img_images_debian_qemu_virt-manager-6.1.Systeme-fichiers.png_10" loading="lazy" src="/images/debian/qemu/virt-manager-6.1.Systeme-fichiers.png" type="image/png" width="756">
        </picture>
    </a>
    <figcaption>virt-manager : activer le système de fichiers</figcaption>
</figure></li>
</ul>
</li>
</ol>
<p>Au redémarrage de la VM, le chemin de la cible sera privilégié en tant
que lecteur Z:… <em>si bien sûr, vous avez réalisé l&rsquo;installation des deux
binaires WinFSP et VirtIO ; sinon faites-le.</em></p>
<h3 id="winfsp">WinFSP</h3>
<p>
                <figure role="figure" aria-label="Démarrage de l’installation de WinFSP">
    <a href="/images/debian/qemu/WinFSP-installer-1.start.png" title="Démarrage de l’installation de WinFSP">
        <picture>
            <source srcset="/images/debian/qemu/WinFSP-installer-1.start.png.avif" type="image/avif"><source srcset="/images/debian/qemu/WinFSP-installer-1.start_hu_4de7c1f187242f0f.webp" type="image/webp">
            <img alt="Démarrage de l’installation de WinFSP" height="386" id="img_images_debian_qemu_WinFSP-installer-1.start.png_11" loading="lazy" src="/images/debian/qemu/WinFSP-installer-1.start.png" type="image/png" width="498">
        </picture>
    </a>
    <figcaption>Démarrage de l’installation de WinFSP</figcaption>
</figure></p>
<p>
                <figure role="figure" aria-label="Phase de personnalisation de l’installation de WinFSP">
    <a href="/images/debian/qemu/WinFSP-installer-2.custom-setup.png" title="Phase de personnalisation de l’installation de WinFSP">
        <picture>
            <source srcset="/images/debian/qemu/WinFSP-installer-2.custom-setup.png.avif" type="image/avif"><source srcset="/images/debian/qemu/WinFSP-installer-2.custom-setup_hu_11961c67b86e938e.webp" type="image/webp">
            <img alt="Phase de personnalisation de l’installation de WinFSP" height="389" id="img_images_debian_qemu_WinFSP-installer-2.custom-setup.png_12" loading="lazy" src="/images/debian/qemu/WinFSP-installer-2.custom-setup.png" type="image/png" width="494">
        </picture>
    </a>
    <figcaption>Phase de personnalisation de l’installation de WinFSP</figcaption>
</figure></p>
<ul>
<li>
<p>Veillez à ce que le module <strong>Core</strong> soit validé - <em>ce qui est normalement le cas par défaut</em>.</p>
</li>
<li>
<p>Terminez classiquement l&rsquo;installation, sans autre détail.</p>
</li>
</ul>
<h3 id="virtio">VirtIO</h3>
<p>
                <figure role="figure" aria-label="Démarrage de l’installation de Virtio-win">
    <a href="/images/debian/qemu/Virtio-win-installer-1.start.png" title="Démarrage de l’installation de Virtio-win">
        <picture>
            <source srcset="/images/debian/qemu/Virtio-win-installer-1.start.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Virtio-win-installer-1.start_hu_c997569a1a4bab32.webp" type="image/webp">
            <img alt="Démarrage de l’installation de Virtio-win" height="386" id="img_images_debian_qemu_Virtio-win-installer-1.start.png_13" loading="lazy" src="/images/debian/qemu/Virtio-win-installer-1.start.png" type="image/png" width="501">
        </picture>
    </a>
    <figcaption>Démarrage de l’installation de Virtio-win</figcaption>
</figure></p>
<p>
                <figure role="figure" aria-label="Phase de personnalisation de l’installation de Virtio-win&amp;#34; s=&amp;#34;/debian/qemu/Virtio-win de l’installation de Virtio-win">
    <a href="/images/debian/qemu/Virtio-win-installer-2.custom-setup.png" title="Phase de personnalisation de l’installation de Virtio-win&amp;#34; s=&amp;#34;/debian/qemu/Virtio-win de l’installation de Virtio-win">
        <picture>
            <source srcset="/images/debian/qemu/Virtio-win-installer-2.custom-setup.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Virtio-win-installer-2.custom-setup_hu_e52f002196847499.webp" type="image/webp">
            <img alt="Phase de personnalisation de l’installation de Virtio-win&#34; s=&#34;/debian/qemu/Virtio-win de l’installation de Virtio-win" height="391" id="img_images_debian_qemu_Virtio-win-installer-2.custom-setup.png_14" loading="lazy" src="/images/debian/qemu/Virtio-win-installer-2.custom-setup.png" type="image/png" width="500">
        </picture>
    </a>
    <figcaption>Phase de personnalisation de l’installation de Virtio-win&amp;#34; s=&amp;#34;/debian/qemu/Virtio-win de l’installation de Virtio-win</figcaption>
</figure></p>
<ul>
<li>
<p>Veillez à ce que le module <strong>Viofs</strong> soit validé - <em>ce qui est normalement le cas par défaut</em>.</p>
</li>
<li>
<p>Pendant la phase d&rsquo;installation:</p>
<ul>
<li>l&rsquo;affichage de la VM va clignoter et se redimentionner automatiquement - <em>c&rsquo;est normal.</em></li>
<li>le copier-coller entre l&rsquo;hôte et la VM est disponible, aussi.</li>
</ul>
</li>
<li>
<p>Une fois l&rsquo;installation terminée, allez dans le gestionnaire de services :</p>
<ul>
<li>Déroulez jusqu&rsquo;au service <strong>Virtio-FS Service</strong>, double-cliquez dessus
<ul>
<li>changez le type de démarrage pour le mettre en mode <strong>Automatique</strong>
en lieu du mode <strong>Manuel</strong></li>
<li>cliquez sur le bouton [ Démarrer ]

                <figure role="figure" aria-label="Gestion du service Virtio-FS">
    <a href="/images/debian/qemu/Virtio-win-installer-3.service.png" title="Gestion du service Virtio-FS">
        <picture>
            <source srcset="/images/debian/qemu/Virtio-win-installer-3.service.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Virtio-win-installer-3.service_hu_55bc71fc874be75f.webp" type="image/webp">
            <img alt="Gestion du service Virtio-FS" height="593" id="img_images_debian_qemu_Virtio-win-installer-3.service.png_15" loading="lazy" src="/images/debian/qemu/Virtio-win-installer-3.service.png" type="image/png" width="806">
        </picture>
    </a>
    <figcaption>Gestion du service Virtio-FS</figcaption>
</figure>

                <figure role="figure" aria-label="Démarrage du service Virtio-FS">
    <a href="/images/debian/qemu/Virtio-win-installer-4.service-start.png" title="Démarrage du service Virtio-FS">
        <picture>
            <source srcset="/images/debian/qemu/Virtio-win-installer-4.service-start.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Virtio-win-installer-4.service-start_hu_3aa699bb47eae0a0.webp" type="image/webp">
            <img alt="Démarrage du service Virtio-FS" height="513" id="img_images_debian_qemu_Virtio-win-installer-4.service-start.png_16" loading="lazy" src="/images/debian/qemu/Virtio-win-installer-4.service-start.png" type="image/png" width="406">
        </picture>
    </a>
    <figcaption>Démarrage du service Virtio-FS</figcaption>
</figure></li>
</ul>
</li>
</ul>
</li>
<li>
<p>Redémarrez la VM</p>
</li>
<li>
<p>Une fois à nouveau dans la session, cliquez sur l&rsquo;explorateur de fichiers,
puis sur <strong>Ce PC</strong>, vous devrez y trouver le lecteur Z: connecté sur C:\vmshare. <br>
Vous pouvez maintenant faire transiter les fichiers désirés entre l&rsquo;hôte et la VM.

                <figure role="figure" aria-label="Vue de l’Explorateur de Fichiers Z:">
    <a href="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z.png" title="Vue de l’Explorateur de Fichiers Z:">
        <picture>
            <source srcset="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z_hu_bf089e9b7117a2fa.webp" type="image/webp">
            <img alt="Vue de l’Explorateur de Fichiers Z:" height="499" id="img_images_debian_qemu_Windows11-Fichiers-vue-vmshare-Z.png_17" loading="lazy" src="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z.png" type="image/png" width="1127">
        </picture>
    </a>
    <figcaption>Vue de l’Explorateur de Fichiers Z:</figcaption>
</figure></p>
</li>
</ul>
<hr>
<h4 id="test-partage-fichier">Test partage fichier</h4>
<p>
                <figure role="figure" aria-label="Depuis la VM : Vue de l’Explorateur de Fichiers Z: du fichier True.txt">
    <a href="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z-True.png" title="Depuis la VM : Vue de l’Explorateur de Fichiers Z: du fichier True.txt">
        <picture>
            <source srcset="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z-True.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z-True_hu_f1d645367e4c6adb.webp" type="image/webp">
            <img alt="Depuis la VM : Vue de l’Explorateur de Fichiers Z: du fichier True.txt" height="498" id="img_images_debian_qemu_Windows11-Fichiers-vue-vmshare-Z-True.png_18" loading="lazy" src="/images/debian/qemu/Windows11-Fichiers-vue-vmshare-Z-True.png" type="image/png" width="799">
        </picture>
    </a>
    <figcaption>Depuis la VM : Vue de l’Explorateur de Fichiers Z: du fichier True.txt</figcaption>
</figure></p>
<p>
                <figure role="figure" aria-label="Depuis l’hôte : Vue de l’Explorateur de Fichiers du fichier True.txt">
    <a href="/images/debian/qemu/Host-Fichiers-vue-vmshare-True.png" title="Depuis l’hôte : Vue de l’Explorateur de Fichiers du fichier True.txt">
        <picture>
            <source srcset="/images/debian/qemu/Host-Fichiers-vue-vmshare-True.png.avif" type="image/avif"><source srcset="/images/debian/qemu/Host-Fichiers-vue-vmshare-True_hu_bdaef7b55d996162.webp" type="image/webp">
            <img alt="Depuis l’hôte : Vue de l’Explorateur de Fichiers du fichier True.txt" height="354" id="img_images_debian_qemu_Host-Fichiers-vue-vmshare-True.png_19" loading="lazy" src="/images/debian/qemu/Host-Fichiers-vue-vmshare-True.png" type="image/png" width="763">
        </picture>
    </a>
    <figcaption>Depuis l’hôte : Vue de l’Explorateur de Fichiers du fichier True.txt</figcaption>
</figure></p>
<hr>
<p>Voilà !</p>
<p>À partir de maintenant, vous êtes opérationnel ;)</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="incapable-de-trouver-un-virtiofsd-satisfaisant">Incapable de trouver un virtiofsd satisfaisant</h3>
<p><abbr title="Question">Q</abbr>
 : Après avoir ajouté le système de fichiers pour le
partage de fichiers entre l&rsquo;hôte et la VM, la VM refuse de démarrer avec le message
d&rsquo;erreur suivant : <strong>incapable de trouver un virtiofsd satisfaisant</strong> ; que se
passe-t-il !?</p>
<p><abbr title="Réponse">R</abbr>
 : Depuis QEMU v8, le projet a cessé d&rsquo;inclure virtiofsd ;
ce dernier est ajouté en tant que paquet dans le dépôt officiel Debian. Si ce
n&rsquo;est pas fait, suite à une migration Debian, par exemple, ajoutez-le !</p>
<h3 id="virtio-fs-ne-démarre-pas">Virtio-FS ne démarre pas</h3>
<p><abbr title="Question">Q</abbr>
 : Le service Virtio-FS refuse de démarrer !</p>
<p><abbr title="Réponse">R</abbr>
 : Avez-vous installé WinFSP en premier ? Si ce
n&rsquo;est pas le cas, faites-le ; ensuite vous pourrez le démarrer.</p>
<hr>
<h3 id="le-partage-de-fichiers-nest-pas-actif">Le partage de fichiers n&rsquo;est pas actif</h3>
<p><abbr title="Question">Q</abbr>
 : J&rsquo;ai redémarré la VM, mais le partage de fichiers
sur Z: n&rsquo;est pas actif !</p>
<p><abbr title="Réponse">R</abbr>
 :</p>
<ol>
<li>Dans les paramètres de la VM, avez-vous bien paramétré un <strong>Système de fichiers</strong> ?
<ul>
<li>Vérifiez vos <strong>chemin de la source</strong> <em>(sur l&rsquo;hôte)</em> et <strong>chemin de la cible</strong>
(<em>celui dans la VM)</em>.</li>
</ul>
</li>
<li>Avez-vous bien paramétré le service Virtio-FS ? Vérifiez qu&rsquo;il soit démarré !</li>
</ol>
<h2 id="documentations">Documentations</h2>
<ul>
<li>
<p><a href="https://libvirt.org/formatdomain.html" rel="external">https://libvirt.org/formatdomain.html</a></p>
</li>
<li>
<p><a href="https://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers" rel="external">https://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers</a></p>
</li>
<li>
<p><a href="https://www.spice-space.org/" rel="external">https://www.spice-space.org/</a></p>
</li>
<li>
<p><a href="https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md" rel="external">https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md</a></p>
</li>
<li>
<p><a href="https://www.debugpoint.com/install-windows-ubuntu-virt-manager/" rel="external">https://www.debugpoint.com/install-windows-ubuntu-virt-manager/</a></p>
</li>
<li>
<p><a href="https://www.debugpoint.com/kvm-share-folder-windows-guest/" rel="external">https://www.debugpoint.com/kvm-share-folder-windows-guest/</a></p>
</li>
<li>
<p><a href="https://getlabsdone.com/how-to-enable-tpm-and-secure-boot-on-kvm/" rel="external">https://getlabsdone.com/how-to-enable-tpm-and-secure-boot-on-kvm/</a></p>
</li>
<li>
<p><a href="https://getlabsdone.com/how-to-install-windows-11-on-kvm/" rel="external">https://getlabsdone.com/how-to-install-windows-11-on-kvm/</a></p>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<p>Tout particulièrement à @Clochette ;)</p>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Virtualiser Windows 11 sous Debian Sid avec QEMU]]></summary>
        <published>2024-02-03T14:21:48+01:00</published>
        <updated>2026-03-08T02:41:09+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b6fa3ab2-d693-53f5-0e5b-9d2762350f62</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sysclean/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: sysclean : un outil pour nettoyer son OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="sysclean" scheme="http://doc.huc.fr.eu.org/fr/tags/sysclean/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Sysclean est un script <a href="http://man.openbsd.org/perl" rel="external">perl(1)</a> conçu
pour aider à supprimer les fichiers obsolètes entre chacune des
mises-à-niveau d&rsquo;OpenBSD.</p>
<p>Par lui-même, sysclean ne retire aucun fichier ; il compare les fichiers
installés par référence à ce qui devrait être dans le système de base
et prend en compte les paquets installés.</p>
<p>Les options sont :</p>
<ul>
<li><code>-a</code> : liste tous les fichiers installés par les packages</li>
<li><code>-p</code> : liste les noms des packages utilisant des fichiers obsolètes</li>
<li><code>-i</code> : inclut les noms de fichiers à ignorer, en utilisant le fichier
<code>/etc/sysclean.ignore</code> - un par ligne, chemin absolu vers le fichier.</li>
</ul>
<h2 id="processus">Processus</h2>
<p>Vérifions les packages &ldquo;obsolètes&rdquo; : <code># sysclean -p</code></p>
<p>Si le résultat convient à nos attentes, on effectue : <br>
<code># pkg_delete $(sysclean -p | awk '{print $2}')</code></p>
<p>Et, pour terminer, retirons les dépendances inutiles : <br>
<code># pkg_delete -a</code></p>
<hr>
<h2 id="astuce">Astuce</h2>
<p>L&rsquo;autre outil, lui, natif au système de base sur OpenBSD est
<code><a class="inside" href="/fr/sys/openbsd/pkg/#etat" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">pkg_check</a>
</code> ;-)</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer les fichiers obsolètes sous OpenBSD, grâce à l&#39;outil système, nommé &#39;sysclean&#39;]]></summary>
        <published>2023-05-10T16:24:58+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c5e5dd7a-7d49-70a1-3392-4ee7153f699b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/unbound-dot/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT &#43; Unbound : utiliser le protocole DoT </title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <category term="DoT" scheme="http://doc.huc.fr.eu.org/fr/tags/dot/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le propos de cet article est d&rsquo;ajouter unbound pour permettre les requêtes
















<span lang="en">DNS <em>(Domain Name Service)</em></span>































































































 sur le protocole 




















<span lang="en">DoT <em>(DNS-over-TCP)</em></span>


























































































, tout en modifiant
légèrement dnsmasq, installé par défaut.</p>
<p>Le but est de :</p>
<ul>
<li>chiffrer le trafic DNS afin d&rsquo;améliorer la confidentialité de celui-ci.</li>
<li>prévenir d&rsquo;une fuite DNS et les détournements de votre trafic 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































</li>
<li>bypasser les restrictions régionales ou celles du 





















<span lang="fr">FAI <em>(Fournisseur d&#39;Accès Internet)</em></span>

























































































.</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Installons les paquets nécessaires : <strong>unbound unbound-control luci-app-unbound</strong></p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# opkg update
:# opkg install unbound unbound-control luci-app-unbound
</code></pre><p>Il peut être utile d&rsquo;installer ces autres paquets liés à unbound :</p>
<ul>
<li><strong>unbound-checkconf</strong> : qui permet de s&rsquo;assurer de la conformité de la
configuration</li>
<li><strong>unbound-control-setup</strong> : qui permet d&rsquo;installer/créer les certificats
nécessaires pour le contrôle de l&rsquo;outil</li>
<li><strong>unbound-host</strong> : pour tester…</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="dnsmasq">dnsmasq</h3>
<p>Éditons le fichier de configuration du serveur dnsmasq <code>/etc/config/dhcp</code>,
pour s&rsquo;assurer des deux options suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">option noresolv &#39;1&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">list server &#39;127.0.0.1#531&#39;</span>
</span></span></code></pre></div><ul>
<li>la première oblige à ne pas utiliser le fichier <code>/etc/resolv.conf</code></li>
<li>la seconde oblige à rediriger les requêtes DNS localement vers le port
choisi, ici <code>531</code>.</li>
</ul>
<hr>
<p>Bien-sûr, ces options peuvent être modifiées directement par LuCI :</p>
<ul>
<li>onglet &lsquo;Resolv and Hosts Files&rsquo; &gt; option <strong>Ignore resolv file</strong>, pour
la première</li>
<li>onglet &lsquo;General Settings&rsquo; &gt; option <strong>DNS forwardings</strong>, pour la seconde.</li>
</ul>
<hr>
<p>Quant à l&rsquo;usage de la commande <code>uci</code> dans votre terminal :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci set dhcp.@dnsmasq[0].noresolv=&#39;1&#39;
uci set dhcp.@dnsmasq[0].server=&#39;127.0.0.1#531&#39;
uci commit
</code></pre><hr>
<p>Pensez à <strong>redémarrer le service dnsmasq</strong> !</p>
<h3 id="unbound">unbound</h3>
<p>La chose la plus simple est d&rsquo;activer Unbound, et de cocher l&rsquo;option
<strong>Manual Conf</strong> pour modifier manuellement le fichier de configuration,
au-travers de LuCI.
Ajoutez vos réseaux dans l&rsquo;option <strong>Trigger Networks</strong>, à-minima <strong>lan</strong>.</p>
<ul>
<li>Fichier de configuration : <code>/var/lib/unbound/unbound.conf</code></li>
</ul>
<hr>
<p>Les changements minimum à faire correspondent aux variables suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server:</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">port: 531</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">do-ip4: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">do-ip6: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">do-tcp: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-identity: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-version: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">qname-minimisation: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">prefetch: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">rrset-roundrobin: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">minimal-responses: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-cert-bundle: &#34;/etc/ssl/certs/ca-certificates.crt&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><p>À-propos du numéro de port choisi, ici <code>531</code> : non, on ne choisit pas
<code>5353</code> qui est réservé normalement au service mdns ; bien-sûr, vous pouvez
le modifier, faites-le en conséquence dans la configuration de dnsmasq,
mais veillez à le choisir dans le contexte des numéros de ports privilégiés,
à savoir en deçà des 1024 premiers…</p>
<hr>
<p>⇒ Pensez absolument à ajouter/modifier des variables <code>access-control</code> pour
n&rsquo;autoriser que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>    <span style="color:#06b6ef">access-control: 0.0.0.0/0 refuse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">access-control: ::0/0 refuse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">access-control: 127.0.0.0/8 allow</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">access-control: ::1 allow</span>
</span></span></code></pre></div><p>Puis à déclarer l&rsquo;adressage IPv(4|6) de votre LAN, voire de votre Wifi…</p>
<hr>
<p>Il est nécessaire ensuite de modifier la section <code>forward-zone</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">forward-zone:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: &#34;.&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-tls-upstream: yes</span>
</span></span></code></pre></div><p>Puis d&rsquo;ajouter toutes les adresses IP de serveurs concernés par DoT ;
bien-sûr les deux protocoles IPv4 et IPv6 sont fonctionnels.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 9.9.9.9@853       # Quad9</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 1.1.1.1@853       # Cloudflare</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 149.112.112.112@853       # Quad9 secondaire</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 1.0.0.1@853       # Cloudflare secondaire</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2620:fe::fe@853       # Quad9 / IPv6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2606:4700:4700::1111@853  # Cloudflare / IPv6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2606:4700:4700::1001@853  # Cloudflare secondaire / IPv6</span>
</span></span></code></pre></div><p>Cet exemple ci-dessus montre l&rsquo;usage des &ldquo;grands&rdquo; de ce monde…
Voici pour le propos des alternatives intéressantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>    <span style="color:#776e71"># FDN DoT</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 80.67.169.12@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 80.67.169.40@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:910:800::12@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:910:800::40@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># dns.sb</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 185.222.222.222@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 45.11.45.11@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a09::@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a11::@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># dns4eu</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 86.54.11.11@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 86.54.11.211@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a13:1001::86:54:11:11@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a13:1001::86:54:11:211@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># dot.bortzmeyer.fr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 193.70.85.11@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:41d0:302:2200::180@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># applied-privacy.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 146.255.56.98@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a02:1b8:10:234::2@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># cleanbrowsing.org: family filter https://cleanbrowsing.org/filters/</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 185.228.168.168@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 185.228.169.168@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a0d:2a00:1::@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a0d:2a00:2::@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># cz.nic</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 193.17.47.1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 185.43.135.1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 2001:148f:ffff::1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 2001:148f:fffe::1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># dnsforfamily.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 78.47.64.161@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 94.130.180.225@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a01:4f8:1c0c:40db::1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a01:4f8:1c17:4df8::1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># he.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 74.82.42.42@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#forward-addr: 2001:470:20::2@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># libredns.gr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 116.202.176.26@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2a01:4f8:1c0c:8274::1@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># dns4all</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 194.0.5.3@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 194.0.5.64@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:678:8::3@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:678:8::64@853</span>
</span></span></code></pre></div><hr>
<p>Voilà pour la configuration de base, qui doit/devrait permettre d&rsquo;utiliser
unbound conjointement avec dnsmasq.</p>
<p>Pensez impérativement à redémarrer le service unbound !</p>
<h2 id="vérifications">Vérifications</h2>
<p>Si vous avez eu l&rsquo;idée d&rsquo;installer l&rsquo;outil <strong>unbound-checkconf</strong>, c&rsquo;est
le moment de l&rsquo;exécuter pour vérifier que les modifications/écritures
faites dans le fichier de configuration sont correctes.
Si tout va bien, l&rsquo;outil vous retournera ce message d&rsquo;information :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# unbound-checkconf
unbound-checkconf: no errors in /var/lib/unbound/unbound.conf
</code></pre><p>S&rsquo;il y a des erreurs, il vous dira où !</p>
<hr>
<p>Si vous avez eu l&rsquo;idée d&rsquo;installer l&rsquo;outil <strong>unbound-host</strong>, il sera possible
de tester la connexion qui devrait être sécurisée, de telle manière, par
exemple :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# unbound-host -vf /var/lib/unbound/root.key com.
com. has no address (secure)
com. has no IPv6 address (secure)
com. has no mail handler record (secure)
</code></pre><p>Faites de même pour les adresses <strong><a href="https://www.ripe.net" rel="external">www.ripe.net</a></strong>, <strong><a href="https://www.afnic.fr" rel="external">www.afnic.fr</a></strong>,
<strong>dnssec.cz</strong>.
La mention <strong>(secure)</strong> assure de la connexion sécurisée.</p>
<h2 id="contrôler">Contrôler</h2>
<p>Un petit laïus à-propos du fait de contrôler le fonctionnement d&rsquo;unbound.
Il est nécessaire d&rsquo;initialiser le paramètrage :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# unbound-control-setup
setup in directory /var/lib/unbound/
generating unbound_server.key
Generating RSA private key, 3072 bit long modulus
...............................................................................................................++
............................................................++
e is 65537 (0x10001)
generating unbound_control.key
Generating RSA private key, 3072 bit long modulus
........................................................................++
..................++
e is 65537 (0x10001)
create unbound_server.pem (self signed certificate)
create unbound_control.pem (signed client certificate)
Signature ok
subject=/CN=unbound-control
Getting CA Private Key
Setup success. Certificates created. Enable in unbound.conf file to use
</code></pre><p>Puis de modifier le fichier de configuration d&rsquo;unbound, pour ajouter/décommenter
la section <code>remote-control</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">remote-control:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-enable: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-interface: 127.0.0.1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-interface: ::1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-port: 8953</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-use-cert: no</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">server-key-file: &#34;/var/lib/unbound/unbound_server.key&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">server-cert-file: &#34;/var/lib/unbound/unbound_server.pem&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-key-file: &#34;/var/lib/unbound/unbound_control.key&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-cert-file: &#34;/var/lib/unbound/unbound_control.pem&#34;</span>
</span></span></code></pre></div><p><strong>Après avoir redémarré le service</strong>, il ne reste plus qu&rsquo;à tester avec
l&rsquo;outil <code>unbound-control</code>, tel que pour l&rsquo;exemple :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# unbound-control -s ::1 status
version: 1.17.0
verbosity: 1
threads: 4
modules: 2 [ validator iterator ]
uptime: 3482 seconds
options: reuseport control
unbound (pid 32307) is running...
</code></pre><p>Il est ainsi possible de connaître la valeur de toute option par l&rsquo;usage
de l&rsquo;option <code>get_option</code> suivie du nom de l&rsquo;option.
De même, il reste possible de faire un dump du cache pour analyse du flux,
par le biais de l&rsquo;option <code>dump_cache</code> redirigé vers un nom de fichier.</p>
<hr>
<p>Voilà, c&rsquo;est terminé.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Et sinon, OpenWRT peut aussi agir en tant que proxy 

















<span lang="en">DoH <em>(DNS-over-HTTPS)</em></span>





























































































;
n&rsquo;hésitez pas à lire : 
<a class="inside" href="/fr/sys/openwrt/dns-doh-proxy/" title="Lien interne vers l&#39;article : 'OpenWRT : proxy DNS DoH'">OpenWRT : proxy DNS DoH</a>

</li>
</ul>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Ajouter unbound pour faire des requêtes DNS chiffrées par le protocole DoT à OpenWRT.]]></summary>
        <published>2023-02-19T15:37:43+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:927c0ac4-4166-1234-b244-167df7dc173b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vm-debian-11-bullseye/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [OpenBSD :: Virtualisation] Debian Bullseye (11.x)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Bullseye" scheme="http://doc.huc.fr.eu.org/fr/tags/bullseye/" />
        <category term="vmd" scheme="http://doc.huc.fr.eu.org/fr/tags/vmd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La virtualisation de machine virtuelle sous OpenBSD est officiellement
disponible nativement dans le système de base depuis OpenBSD 5.9.</p>
<ul>
<li>Version : <strong>native</strong></li>
<li>OS : OpenBSD <strong>7.0</strong> → <strong>7.2</strong></li>
</ul>
<p>Pour rappel : utiliser le virtualisateur vmd d&rsquo;OpenBSD a quelques restrictions,
dont celles de ne pas pouvoir utiliser d&rsquo;interface graphique, …</p>
<h2 id="pré-requis">Pré-requis</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Ce tutoriel ne documente pas dans les moindres détails
les phases d&rsquo;installation, voire de configuration.</p>
<p>Il est <strong>VRAIMENT</strong> nécessaire de faire preuve de réflexion, discernement
et d&rsquo;avoir un minimum de compétences, pour comprendre les liens entre les
différentes briques !</p>
<p>Merci de votre compréhension…</p>
</div>

<p>Il est nécessaire que votre machine sur laquelle vous souhaitez virtualiser
ait un CPU compatible avec les fonctions adéquates. Pour le vérifier, tapez
dans votre terminal/console la commande suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>:$ dmesg | egrep <span style="color:#48b685">&#39;(VMX/EPT|SVM/RVI)&#39;</span>
</span></span></code></pre></div><p>La réponse du système doit être :</p>
<p>⇒ pour CPU Intel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT
</span></span></code></pre></div><p>⇒ pour CPU Amd :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: SVM/RVI
</span></span></code></pre></div><p>Si aucune ligne n&rsquo;apparaît, aucune virtualisation ne sera possible. Par
acquis de conscience, vérifiez votre BIOS|UEFI que celle-ci ne soit pas
désactivée.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>De même, en rapport avec les failles CPU relatives à Meltdown, Spectre,
certains CPU Intel sont patchés pour remédier à <a href="https://www.intel.fr/content/www/fr/fr/architecture-and-technology/l1tf.html" rel="external">L1TF</a>.
Sous OpenBSD, ces CPU reçoivent un correctif approprié. Malheureusement,
cela impacte la virtualisation et rend celle-ci difficile pour certains,
voire impossible.<br>
Vous pouvez vous retrouver dans la situation où vous auriez un CPU
compatible, mais dans les faits, la virtualisation ne pourrait être
pleinement fonctionnelle.</p>
<p><em>Préférez AMD, en attendant ARM… voire RISC V.</em></p>
</div>

<hr>
<p>Il est nécessaire d&rsquo;installer le firmware <code>vmm</code> pour que le kernel gère.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# fw_update vmm
</span></span></code></pre></div><hr>
<p>Par convention, créons un répertoire &lsquo;&lsquo;vm&rsquo;&rsquo; dans notre répertoire personnel,
et nous travaillerons à partir de celui-ci : <br>
<code>:$ mkdir vm &amp;&amp; cd vm</code></p>
<h3 id="précisions-réseaux">Précisions réseaux</h3>
<ul>
<li>L&rsquo;interface <code>vether0</code> de l&rsquo;hôte aura pour adresse IPv4 : <code>192.168.0.1</code>,
cette adresse IP sera l&rsquo;adresse de la passerelle pour l&rsquo;interface
réseau de la VM.</li>
<li>L&rsquo;interface <code>enp0s3</code> de la VM Debian aura pour adresse IPv4 : <code>192.168.0.2</code></li>
<li>Dans les deux cas, le masque de réseau est de 24 bits.</li>
<li>La passerelle de la VM sera l&rsquo;adresse IP de l&rsquo;interface vether ;)</li>
<li>Les serveurs DNS renseignés dans le fichier <code>/etc/resolv.conf</code> de la VM
sont les serveurs publics de la FDN, respectueux de la confidentialité…</li>
<li>Ces même serveurs DNS peuvent être renseignés dans la règle PF de
redirection de flux DNS vers la VM.</li>
<li>Cet article ne montre rien concernant, ou si peu, le fonctionnement
avec le protocole IPv6, mais les principes ci-dessus s&rsquo;appliquent,
pourvu que vous comprenez ce que vous faites.</li>
</ul>
<h2 id="création-de-limage-qcow2">Création de l&rsquo;image qcow2</h2>
<p>Dans les deux cas présentés, nous commencerons par créer la VM, très
simplement avec l&rsquo;outil natif à OpenBSD, nommé <code>vmctl</code> :</p>
<p><code>:$ vmctl create -s 50G ~/vm/bullseye.qcow2</code></p>
<h2 id="téléchargement-de-liso-debian">Téléchargement de l&rsquo;iso Debian</h2>
<p>Téléchargeons l&rsquo;iso Debian :</p>
<p><code>:$ ftp https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/{debian-11.5.0-amd64-netinst.iso,SHA512SUMS}</code></p>
<p>Une fois téléchargée, vérifions sa somme de contrôle : \</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ sha512 -C SHA512SUMS debian-10.1.0-amd64-netinst.iso
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>SHA512<span style="color:#5bc4bf">)</span> debian-10.1.0-amd64-netinst.iso: OK
</span></span></code></pre></div><p>Si <strong>OK</strong>, alors c&rsquo;est bon… <span class="red">sinon, re-téléchargez</span>
 !</p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration : <code>/etc/vm.conf</code>.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">switch &#34;sw&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">interface bridge0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">vm &#34;bullseye&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">disable</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">memory 1G</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">cdrom /home/id/vm/debian-11.5.0-amd64-netinst.iso</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">disk /home/id/vm/bullseye.qcow2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">interface { switch &#34;sw&#34; }</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">owner votre-identifiant</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Bien sûr, remplacez :</p>
<ul>
<li><code>/home/id</code> par votre répertoire home</li>
<li><code>votre-identifiant</code> par votre identifiant de session</li>
</ul>
<hr>
<p>Vérifiez la configuration à l&rsquo;aide de l&rsquo;option <code>-n</code> de vmd :</p>
<p><code>:$ vmd -n</code></p>
<hr>
<p>Après avoir configuré les <a href="/fr/sys/openbsd/vm-debian-11-bullseye/#interfaces-réseaux">interfaces réseaux</a>,
il faut maintenant démarrer le service de gestion des VMs :  <br>
<code>:# rcctl enable vmd &amp;&amp; rcctl start vmd</code></p>
<p>puis il faut s&rsquo;occuper de la <a href="/fr/sys/openbsd/vm-debian-11-bullseye/#nat">traduction d&rsquo;adresses réseaux</a>,
et aussi des <a href="/fr/sys/openbsd/vm-debian-11-bullseye/#pf">règles du parefeu</a>…</p>
<h3 id="interfaces-réseaux">Interfaces réseaux</h3>
<p>Créons les interfaces réseaux nécessaires que sont <code>vether0</code> et <code>bridge0</code>
qui permettront un contrôle fin de l&rsquo;adressage IP et des règles PF.</p>
<h4 id="bridge0">bridge0</h4>
<p>Le fichier relatif est <code>/etc/hostname.bridge0</code> :</p>
<p><code>:# echo &quot;add vether0&quot; &gt; /etc/hostname.bridge0</code></p>
<h4 id="vether0">vether0</h4>
<p>Le fichier relatif est <code>/etc/hostname.vether0</code> :</p>
<p><code>:#  echo &quot;inet 192.168.0.1 255.255.255.0&quot; &gt; /etc/hostname.vether0</code></p>
<hr>
<p>Une fois les fichiers d&rsquo;interfaces créés, donnez des droits 0600 dessus,
puis démarrez les deux interfaces :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# chmod <span style="color:#f99b15">0600</span> /etc/hostname.<span style="color:#5bc4bf">{</span>bridge,vether<span style="color:#5bc4bf">}</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>:# sh /etc/netstart <span style="color:#5bc4bf">{</span>bridge,vether<span style="color:#5bc4bf">}</span><span style="color:#f99b15">0</span>
</span></span></code></pre></div><h3 id="nat">NAT</h3>
<p>Dans ce contexte où la VM invitée est sur un segment réseau différent de
l&rsquo;hôte, il faut autoriser la redirection des paquets IP, pour que la VM
puisse communiquer sur Internet - <em>ne serait-ce que pour faire les mises à jour</em>…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# sysctl net.inet.ip.forwarding<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>:# sysctl net.inet6.ip6.forwarding<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span></code></pre></div><p>La première ligne est pour IPv4, la seconde pour IPv6.</p>
<p>Puis, pour garder les paramètres au redémarrage, modifiez le fichier
<code>/etc/sysctl.conf</code> pour ajouter :  <br>
<code>net.inet.ip.forwarding=1</code> <br>
<code>net.inet6.ip6.forwarding=1</code></p>
<h3 id="pf">PF</h3>
<ul>
<li>le fichier de configuration <code>/etc/pf.conf</code></li>
</ul>
<p>Ajouter au moins les règles suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">domain</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;80.67.169.12 80.67.169.40&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match out on egress from (vether0:network) to any nat-to (egress)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick proto { udp tcp } from (vether0:network) to any port domain rdr-to { $domain } port domain</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on vether0 from 127.0.0.1 to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on vether0 from (vether0:network) to any</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><ul>
<li>La première règle indique que tout ce qui vient du réseau lié à l&rsquo;interface
<code>vether0</code> doit être traduit (NATé) vers les adresses IP faisant partie
du groupe <code>egress</code>.</li>
<li>La deuxième règle demande à ce que tout flux entrant qui vient du service
<code>domain</code> (port <code>53</code>) sur les protocoles <code>udp</code> et <code>tcp</code> depuis
le réseau lié à l&rsquo;interface <code>vether0</code> soit redirigée vers le service
en question. <br>
Les adresses IPv4 <code>80.67.169.12</code> et <code>80.67.169.40</code> sont celles des
<a href="https://www.fdn.fr/actions/dns/" rel="external">serveurs DNS publics de la FDN</a>.
<em>Elles peuvent être très bien celle de tout autre serveur DNS</em>.</li>
<li>La troisième règle autorise tout ce qui passe en entrée et en sortie
sur l&rsquo;interface <code>vether0</code> depuis l&rsquo;interface <code>locale</code>  vers ailleurs…</li>
<li>Quant à la quatrième, elle autorise tout du réseau, en entrée et en sortie,
lié à l&rsquo;interface <code>vether0</code> vers partout !</li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<ul>
<li>
<p>Démarrer la VM pour l&rsquo;installation :<br>
<code>:$ vmctl start -c bullseye</code></p>
</li>
<li>
<p>Choisir le menu &ldquo;Install&rdquo; - <strong>NE PAS APPUYEZ sur la touche <kbd>ENTRÉE</kbd></strong> ;
appuyez sur la touche <kbd>TAB</kbd> pour éditer le menu. Il va falloir
corriger la ligne : <br>
<code>&gt; /install.amd/vmlinuz vga=788 initrd=/install.amd/initrd.gz --- quiet</code> en <br>
<code>&gt; /install.amd/vmlinuz vga=off initrd=/install.amd/initrd.gz --- quiet console=ttyS0,115200n8</code> ; <br>
une fois, transformée, appuyez sur la touche <kbd>ENTRÉE</kbd> !</p>
</li>
</ul>
<p>Le reste de l&rsquo;installation de Debian se fait comme tout autre installation…</p>
<p>Lors de la configuration réseau, pensez bien à paramétrer la VM correctement,
si nécessaire, revoyez le chapitre sur les <a href="/fr/sys/openbsd/vm-debian-11-bullseye/#précisions-réseaux">précisions réseaux</a>.</p>
<p>Une fois l&rsquo;installation terminée, ne redémarrez pas par le biais de l&rsquo;installateur,
choisissez d&rsquo;exécuter le shell, puis écrivez la commande : <br>
<code>:# halt</code> afin d&rsquo;arrêter la VM proprement !</p>
<h3 id="pour-finir">Pour finir</h3>
<p>Une fois que vous avez fini l&rsquo;installation de Debian dans votre VM, que
vous avez fait les derniers réglages nécessaires pour son bon fonctionnement,
pensez à éditer à nouveau le fichier <code>/etc/vm.conf</code> :</p>
<ul>
<li>Supprimer/commenter toute écriture relative à la déclaration <code>cdrom</code>…</li>
<li>Remplacer le mot clé <code>disable</code> par <code>enable</code> pour la VM Debian -
si vous désirez que la VM correspondante démarre, soit lors du démarrage
de votre machine, si et seulement si le service <code>vmd</code> est bien actif
et démarré lors du processus de démarrage machine, soit lorsque vous
redémarrez le service <code>vmd</code> par vos soins.</li>
</ul>
<hr>
<p>Voilà !</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="vmctl-vmm-bios-firmware-not-found">vmctl vmm bios firmware not found</h3>
<p>Vous n&rsquo;avez tout simplement pas installé le firmware <strong>vmm</strong> !</p>
<h3 id="vmx_fault_page-uvm_fault-returns-14-gpa0xffffca78-rip0xfbd49">vmx_fault_page: uvm_fault returns 14, GPA=0xffffca78, rip=0xfbd49</h3>
<p>Si vous avez ce message d&rsquo;erreur ou similaire dans dmesg, de fait
malheureusement, vous ne pourrez pas faire de la virtualisation ! :(</p>
<p>Voici un <a href="http://daemonforums.org/showthread.php?t=11628" rel="external">exemple</a> - <em>en anglais</em> -
de CPU Intel patché L1TF où le média de démarrage n&rsquo;était pas trouvé.</p>
<h2 id="documentations">Documentations</h2>
<h3 id="faq">FAQ</h3>
<ul>
<li>Merci de lire la documentation officielle <strong>FAQ Virtualisation</strong> (<a href="https://www.openbsd.org/faq/faq16.html" rel="external">EN</a>),
ou sa traduction officieuse <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/faq16" rel="external">FR</a>.</li>
</ul>
<h3 id="manpage">manpage</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/vmctl.8" title="Page du Manuel OpenBSD pour : vmctl">vmctl(8)</a>
, 
<a class="man" href="https://man.openbsd.org/vmd.8" title="Page du Manuel OpenBSD pour : vmd">vmd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/vm.conf.5" title="Page du Manuel OpenBSD pour : vm.conf">vm.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/vmm.4" title="Page du Manuel OpenBSD pour : vmm">vmm(4)</a>
</li>
</ul>
<h3 id="vm-guest-sur-le-même-réseau-que-lhôte">VM guest sur le même réseau que l&rsquo;hôte.</h3>
<p>Oui, il est possible que la VM invitée fasse partie du même segment IP
que celui de votre hôte.</p>
<p>J&rsquo;explique le propos dans cet article : 
<a class="inside" href="/fr/sys/openbsd/vmd-hote-invite-meme-reseau/" title="Lien interne vers l&#39;article : '[OpenBSD :: Virtualisation] Hôte et invité(s) sont sur le même bateau'">[OpenBSD :: Virtualisation] Hôte et invité(s) sont sur le même bateau</a>

</p>
<p>Si jamais vous vous y essayer après cet article, comprenez bien :</p>
<ul>
<li>le fonctionnement réseau, IP, les interfaces virtuelles bridge, vether,
mais aussi et surtout tap.</li>
<li>que les règles du parefeu sont de fait différentes et son fonctionnement,
aussi !</li>
<li>et que non, dans ce cas, il n&rsquo;y a pas besoin de la redirection <a href="/fr/sys/openbsd/vm-debian-11-bullseye/#nat">NAT</a>,
donc il vous faudra supprimer/commenter les modifications <code>sysctl</code>.</li>
</ul>
<p>Mais tout est fait dans l&rsquo;article, pour que vous compreniez bien le propos.</p>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Virtualiser Debian Bullseye (11.x) sous OpenBSD grâce à vmd]]></summary>
        <published>2022-11-28T17:36:21+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:63c19ccc-c376-cb4c-b079-f051fe3f1796</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/moc/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: moc - Music on Console / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="moc" scheme="http://doc.huc.fr.eu.org/fr/tags/moc/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>MOC</strong> (musique en console) est un lecteur audio en mode console/terminal
pour Linux/Unix conçu pour être puissant et simple à utiliser.</p>
<p>La lecture faite par MOC est fluide, quelle que soit la charge du système
ou des <abbr title="Entrées/Sorties">E/S</abbr>
, car elle utilise le tampon
de sortie dans un thread/processus séparé. Il permet une lecture sans
interruption car le prochain fichier à lire est mis en cache pendant la
lecture du fichier en cours.</p>
<p>Les formats de fichiers supportés sont : MP3, Ogg Vorbis, FLAC, Musepack (mpc),
Speex, Opus, WAVE, tous ceux supportés par la bibliothèque FFmpeg/LibAV
(e.g., WMA, RealAudio, AAC, MP4), AIFF, AU, SVX, Sphere Nist WAV, IRCAM SF,
Creative VOC, SID, wavpack.</p>
<ul>
<li>Site web : <a href="http://moc.daper.net/" rel="external">http://moc.daper.net/</a></li>
<li>Architectures supportées : aarch64 alpha amd64 arm hppa i386 mips64
mips64el powerpc powerpc64 riscv64 sh sparc64</li>
</ul>
<hr>
<p>Ce lecteur audio est pratique pour exécuter de l&rsquo;audio sur un serveur
multimédia, par le biais d&rsquo;une session SSH, en mode console.</p>
<h2 id="installation">Installation</h2>
<p>Sous OpenBSD, <strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>

<strong><code>moc</code></strong></strong> !</p>
<h2 id="utilisation">Utilisation</h2>
<p>Très simplement, dans un terminal ou en mode console, un appel du binaire
<code>mocp</code> suffit. <br>
C&rsquo;est une interface ressemblant à celle de Midnight Commander, avec deux
fenêtres, une à gauche pour naviguer dans le système de fichiers, l&rsquo;autre
affichant la playlist en cours, sinon l&rsquo;espace est vide.</p>
<p>Voici quelques interactions possibles depuis l&rsquo;appui de touches :</p>
<ul>
<li>
<p>la touche <kbd>a</kbd> permet d&rsquo;ajouter un répertoire/fichier dans la playlist</p>
</li>
<li>
<p>la touche <kbd>h</kbd> permet d&rsquo;avoir accès à la liste des différentes commandes</p>
</li>
<li>
<p>la touche <kbd>L</kbd> affiche les paroles si elles sont disponibles</p>
</li>
<li>
<p>la touche <kbd>n</kbd> permet de passer au morceau suivant</p>
</li>
<li>
<p>la touche <kbd>o</kbd> permet de jouer une piste musicale depuis une URL</p>
</li>
<li>
<p>les touches <kbd>p</kbd> et <kbd>ESPACE</kbd> permettent de mettre en pause</p>
</li>
<li>
<p>la touche <kbd>q</kbd> ferme le lecteur, sans arrêter la lecture audio</p>
</li>
<li>
<p>la touche <kbd>Q</kbd> arrête la lecture et ferme le lecteur, et la
connexion au serveur de son</p>
</li>
<li>
<p>la touche <kbd>R</kbd> active ou non la relecture</p>
</li>
<li>
<p>la touche <kbd>s</kbd> arrête la lecture musicale</p>
</li>
<li>
<p>la touche <kbd>S</kbd> active ou non la lecture aléatoire</p>
</li>
<li>
<p>la touche <kbd>V</kbd> permet d&rsquo;enregistrer la playlist, là où vous le
désirez et au nom que vous désirez</p>
</li>
<li>
<p>la touche <kbd>X</kbd> active ou non la prise en charge de la lecture
suivante</p>
</li>
<li>
<p>la touche <kbd>,</kbd> diminue le son de 5%</p>
</li>
<li>
<p>la touche <kbd>.</kbd> augmente le son de 5%</p>
</li>
<li>
<p>etc…</p>
</li>
</ul>
<hr>
<figure>
    <a href="/images/openbsd/mocp.png" title="Capture d&#39;écran du logiciel mocp en cours de fonctionnement">
    <picture>
        
        <source srcset="/images/openbsd/mocp_hu_6bc0ffd41f8066be.webp" type="image/webp">
        
        <img alt="Capture d&#39;écran du logiciel mocp en cours de fonctionnement" height="152" loading="lazy" src="/images/openbsd/mocp_hu_8318cfe41fc16dbc.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Capture d'écran du logiciel mocp en cours de fonctionnement</figcaption>
</figure>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Écouter de l&#39;audio en mode console sous OpenBSD, avec le lecteur mocp, du projet moc]]></summary>
        <published>2022-11-24T18:48:06+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:66458b85-ce84-2f4d-e453-b995ba4f1c46</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/introduction-influxdb-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Influxdb : Introduction (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Introduction" scheme="http://doc.huc.fr.eu.org/fr/tags/introduction/" />
        <category term="Supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <category term="influxdb" scheme="http://doc.huc.fr.eu.org/fr/tags/influxdb/" />
        <content type="html"><![CDATA[<h2 id="introduction">Introduction</h2>
<p><strong>Get&rsquo;in Start: <code>#!/bin/introduction</code></strong></p>
<p><strong>influxdb</strong> est une base de données de séries temporelles. Elle s&rsquo;utilise
en complément de logiciels tiers, tels des services collectant des métriques
systèmes et applications, à intervalles réguliers (<strong>telegraf</strong>, <strong>collectd</strong>)
ainsi que des logiciels générant des graphes personnalisés par le biais
de requêtes sur la base de données (<strong>Grafana</strong>, …)</p>
<h2 id="installation">Installation</h2>
<p>Sous OpenBSD ≤ 7.3, <strong>influxdb</strong> est disponible en tant que paquet,
dans sa version <strong>1.x</strong>.</p>
<p>Un groupe <code>_influx</code> et un utilisateur <code>_influx</code> sont créés.</p>
<h2 id="vérification-de-démarrage">Vérification de démarrage</h2>
<p>⇒ Après avoir démarré le service <strong><code>influxdb</code></strong>, il est possible de vérifier
le bon fonctionnement de la base de données.</p>
<p>Deux manières :</p>
<ol>
<li>En requêtant directement la base de données :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ influx
</span></span><span style="display:flex;"><span>Connected to http://localhost:8086 version unknown
</span></span><span style="display:flex;"><span>InfluxDB shell version: unknown
</span></span><span style="display:flex;"><span>&gt; show databases
</span></span><span style="display:flex;"><span>name: databases
</span></span><span style="display:flex;"><span>name
</span></span><span style="display:flex;"><span>----
</span></span><span style="display:flex;"><span>_internal
</span></span></code></pre></div><ol start="2">
<li>En utilisant l&rsquo;outil <strong>curl</strong> pour tester une réponse locale par requête
HTTP :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ curl -G http://localhost:8086/query --data-urlencode <span style="color:#48b685">&#34;q=SHOW DATABASES&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span><span style="color:#48b685">&#34;results&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;statement_id&#34;</span>:0,<span style="color:#48b685">&#34;series&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;name&#34;</span>:<span style="color:#48b685">&#34;databases&#34;</span>,<span style="color:#48b685">&#34;columns&#34;</span>:<span style="color:#5bc4bf">[</span><span style="color:#48b685">&#34;name&#34;</span><span style="color:#5bc4bf">]</span>,<span style="color:#48b685">&#34;values&#34;</span>:<span style="color:#5bc4bf">[[</span><span style="color:#48b685">&#34;_internal&#34;</span><span style="color:#5bc4bf">]]}]}]}</span>
</span></span></code></pre></div><p>Dans les deux cas, si vous avez le même résultat, c&rsquo;est tout bon !</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration : <code>/etc/influxdb/influxdb.conf</code></p>
<h3 id="utilisateur-admin">Utilisateur admin</h3>
<p>Avant de toucher au fichier de configuration, <strong>créons un premier utilisateur</strong>
administrateur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas influx
</span></span><span style="display:flex;"><span>Connected to http://localhost:8086 version unknown
</span></span><span style="display:flex;"><span>InfluxDB shell version: unknown
</span></span><span style="display:flex;"><span>&gt; CREATE USER admin WITH PASSWORD <span style="color:#48b685">&#39;password&#39;</span> WITH ALL PRIVILEGES
</span></span><span style="display:flex;"><span>&gt; SHOW USERS
</span></span><span style="display:flex;"><span>user   admin
</span></span><span style="display:flex;"><span>----   -----
</span></span><span style="display:flex;"><span>admin true
</span></span><span style="display:flex;"><span>&gt; QUIT
</span></span></code></pre></div><ul>
<li>Ici, le nom de l&rsquo;utilisateur est <em><code>admin</code></em> avec des droits d&rsquo;administrateur.</li>
<li><em><code>password</code></em> est pour l&rsquo;exemple…</li>
</ul>
<p>La prochaine connexion à la base de données nécessitera d&rsquo;utiliser le compte
administrateur.</p>
<p>Là, encore deux manières de faire :</p>
<ol>
<li>connexion puis utilisation de la commande <code>auth</code> :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ influx
</span></span><span style="display:flex;"><span>Connected to http://localhost:8086 version unknown
</span></span><span style="display:flex;"><span>InfluxDB shell version: unknown
</span></span><span style="display:flex;"><span>&gt; auth
</span></span><span style="display:flex;"><span>username: admin
</span></span><span style="display:flex;"><span>password:
</span></span><span style="display:flex;"><span>&gt; *n instructions*
</span></span><span style="display:flex;"><span>&gt; QUIT
</span></span></code></pre></div><ol start="2">
<li>connexion en précisant directement le nom de l&rsquo;utilisateur en argument :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ influx -username admin -password <span style="color:#48b685">&#39;&#39;</span>
</span></span><span style="display:flex;"><span>password:
</span></span><span style="display:flex;"><span>Connected to http://localhost:8086 version unknown
</span></span><span style="display:flex;"><span>InfluxDB shell version: unknown
</span></span><span style="display:flex;"><span>&gt; quit
</span></span></code></pre></div><p><em>(en réalité, il existe d&rsquo;autres manières de faire…)</em></p>
<p>Si c&rsquo;est bon dans les deux cas, c&rsquo;est tout bon !</p>
<p>À partir de maintenant, la base de données n&rsquo;est pas ouverte à tout le monde.</p>
<h3 id="authentification-http">Authentification HTTP</h3>
<p>Pour activer l&rsquo;authentification HTTP, il faut modifier le fichier de configuration.
Aller à la section <code>[http]</code> puis décommenter à minima les variables suivantes :</p>
<ul>
<li><code>enabled = true</code></li>
<li><code>auth-enabled = true</code></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[http]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Determines whether HTTP endpoint is enabled.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">enabled</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Determines whether the Flux query endpoint is enabled.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># flux-enabled = false</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Determines whether the Flux query logging is enabled.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># flux-log-enabled = false</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># The bind address used by the HTTP service.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">bind-address</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;:8086&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Determines whether user authentication is enabled over HTTP/HTTPS.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">auth-enabled</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><p>Puis <strong>redémarrer</strong> le service…</p>
<hr>
<p>Testons à nouveau une requête HTTP :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ curl -G http://localhost:8086/query --data-urlencode <span style="color:#48b685">&#34;q=SHOW DATABASES&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span><span style="color:#48b685">&#34;error&#34;</span>:<span style="color:#48b685">&#34;unable to parse authentication credentials&#34;</span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><p>Puisqu&rsquo;il demande une authentification, utilisons curl en précisant l&rsquo;utilisateur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ curl -G http://localhost:8086/query -u admin -p <span style="color:#48b685">&#39;&#39;</span> --data-urlencode <span style="color:#48b685">&#34;q=SHOW DATABASES&#34;</span>
</span></span><span style="display:flex;"><span>Enter host password <span style="color:#815ba4">for</span> user <span style="color:#48b685">&#39;admin&#39;</span>:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span><span style="color:#48b685">&#34;results&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;statement_id&#34;</span>:0,<span style="color:#48b685">&#34;series&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;name&#34;</span>:<span style="color:#48b685">&#34;databases&#34;</span>,<span style="color:#48b685">&#34;columns&#34;</span>:<span style="color:#5bc4bf">[</span><span style="color:#48b685">&#34;name&#34;</span><span style="color:#5bc4bf">]</span>,<span style="color:#48b685">&#34;values&#34;</span>:<span style="color:#5bc4bf">[[</span><span style="color:#48b685">&#34;_internal&#34;</span><span style="color:#5bc4bf">]]}]}]}</span>
</span></span></code></pre></div><p>Après avoir entré le bon mot-de-passe, la requête pour voir les bases de
données aboutit bien.</p>
<p>Si c&rsquo;est le cas, nous avons réussi le principal : installer influxdb, faire
une configuration de base fonctionnelle. Voilà.</p>
<h3 id="https">HTTPS</h3>
<p>Maintenant, allons plus loin, pour utiliser le protocole HTTPS qui permettra
de sécuriser la connexion avec les autres services, d&rsquo;autant si ceux-ci
sont à distance.</p>
<h4 id="création-des-certificats">Création des certificats</h4>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Dans ce contexte tutoriel, nous utilisons des certificats auto-signés.
En conséquence, ils ne sont pas certifiés par une Autorité de Certification.</p>
<p>Pas besoin de passer par cette étape, si vous utiliser une AC ; il suffit
de renseigner le chemin absolu vers les certificats générés par l&rsquo;AC. <br>
Dans ce cas, allez directement à la partie de la configuration correspondante
à la section <code>[http]</code>.</p>
</div>

<p>Ici, nous utilisons l&rsquo;outil <strong><code>certtool</code></strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ apropos certtool
</span></span><span style="display:flex;"><span>certtool<span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span> - GnuTLS certificate tool
</span></span></code></pre></div><p>Si le paquet <strong>gnutls</strong> n&rsquo;est pas installé, faites-le.</p>
<hr>
<p>Puis avec des droits administrateurs, allez dans <code>/etc/ssl</code>, créer un
répertoire <code>influxdb</code> dans lequel faire les opérations suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /etc/ssl/influxdb
</span></span><span style="display:flex;"><span>:# cd /etc/ssl/influxdb
</span></span></code></pre></div><p>⇒ Création de la clé privée</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# certtool -p --hash SHA3-256 --sec-param ULTRA --outfile <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span>.priv.k.pem
</span></span></code></pre></div><p>⇒ puis création de la clé publique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# certtool -s --load-privkey <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span>.priv.k.pem --outfile <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span>.cert.pem
</span></span></code></pre></div><p>qui vous posera plein de questions concernant l&rsquo;identification, raison
sociale et le but de ce certificat.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Lors de la génération du certificat publique, il vous a été demandé
une période en nombre de jours de validité. Faites-vous un mémo, selon
la périodicité, pour vous générer une nouvelle clé publique, si besoin,
avant la fin de ladite période. Autrement votre service par HTTPS
deviendrait indisponible à date échue.</div>

<p>⇒ modifions les droits utilisateurs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# chown _influx:_influx *.pem
</span></span></code></pre></div><hr>
<p>Ceci étant fait, retournons modifier le fichier de configuration, à nouveau
à la section <code>[http]</code>, mais cette fois-ci pour modifier les valeurs suivantes :</p>
<ul>
<li><code>https-enabled = true</code></li>
<li><code>https-certificate = &quot;/etc/ssl/influxdb/votre-nom-hote.cert.pem&quot;</code></li>
<li><code>https-private-key = &quot;/etc/ssl/influxdb/votre-nom-hote.priv.k.pem&quot;</code></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Determines whether HTTPS is enabled.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">https-enabled</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># The SSL certificate to use when HTTPS is enabled.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">https-certificate</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;/etc/ssl/influxdb/votre-nom-hote.cert.pem&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71"># Use a separate private key location.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">https-private-key</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;/etc/ssl/influxdb/votre-nom-hote.priv.k.pem&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><p>⇒ Relancer le service !</p>
<hr>
<p>Testons la connexion :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ influx -ssl -unsafeSsl -username admin -password <span style="color:#48b685">&#39;&#39;</span>
</span></span><span style="display:flex;"><span>password:
</span></span><span style="display:flex;"><span>Connected to https://localhost:8086 version unknown
</span></span><span style="display:flex;"><span>InfluxDB shell version: unknown
</span></span><span style="display:flex;"><span>&gt; SHOW DATABASES
</span></span><span style="display:flex;"><span>name: databases
</span></span><span style="display:flex;"><span>name
</span></span><span style="display:flex;"><span>----
</span></span><span style="display:flex;"><span>_internal
</span></span><span style="display:flex;"><span>&gt; SHOW USERS
</span></span><span style="display:flex;"><span>user     admin
</span></span><span style="display:flex;"><span>----     -----
</span></span><span style="display:flex;"><span>admin   true
</span></span><span style="display:flex;"><span>&gt; QUIT
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ curl -G https://localhost:8086/query -k -u admin -p <span style="color:#48b685">&#39;&#39;</span> --data-urlencode <span style="color:#48b685">&#34;q=SHOW DATABASES&#34;</span>
</span></span><span style="display:flex;"><span>Enter host password <span style="color:#815ba4">for</span> user <span style="color:#48b685">&#39;admin&#39;</span>:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span><span style="color:#48b685">&#34;results&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;statement_id&#34;</span>:0,<span style="color:#48b685">&#34;series&#34;</span>:<span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#34;name&#34;</span>:<span style="color:#48b685">&#34;databases&#34;</span>,<span style="color:#48b685">&#34;columns&#34;</span>:<span style="color:#5bc4bf">[</span><span style="color:#48b685">&#34;name&#34;</span><span style="color:#5bc4bf">]</span>,<span style="color:#48b685">&#34;values&#34;</span>:<span style="color:#5bc4bf">[[</span><span style="color:#48b685">&#34;_internal&#34;</span><span style="color:#5bc4bf">]]}]}]}</span>
</span></span></code></pre></div><p>Remarquez l&rsquo;utilisation de l&rsquo;option <code>-k</code>, sans elle, étant donné ce
contexte d&rsquo;utilisation de certificats auto-signés, curl refuserait de se
connecter avec le message d&rsquo;erreur suivant : <br>
<code>curl: (60) SSL certificate problem: unable to get local issuer certificate</code></p>
<h3 id="journalisation-http">Journalisation HTTP</h3>
<p>Par défaut, la journalisation des traces HTTP(S) se fait dans le moteur
interne de journalisation d&rsquo;influxdb et sera visible dans le log &lsquo;daemon&rsquo;.</p>
<p>Il est possible de changer ce comportement pour avoir le suivi HTTP(S)
au sein d&rsquo;un fichier dédié. Toujours dans la section <code>[http]</code>, modifiez
la variable <code>access-log-path</code>.</p>
<p>Avant de redémarrer le service, créer impérativement le répertoire dans
lequel influxdb écrira le fichier log et donnez lui les droits systèmes
liés, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /var/log/influxdb/
</span></span><span style="display:flex;"><span>:# chown _influx:_influx /var/log/influxdb/
</span></span></code></pre></div><p>Puis pour la configuration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>  <span style="color:#06b6ef">access-log-path</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;/var/log/influxdb/access.log&#34;</span>
</span></span></code></pre></div><p>Pour finir, pensez à modifier le fichier <code>/etc/newsyslog.conf</code> pour ajouter
une ligne, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">/var/log/influxdb/access.log    _influx:_influx 644     7       *       *       Z</span>
</span></span></code></pre></div><hr>
<h2 id="eod">EOD</h2>
<p><em><strong>End of Documentation</strong></em></p>
<p>Voilà. Maintenant, influxdb est prêt pour une utilisation interne et
n&rsquo;attend plus qu&rsquo;à être configurer pour discuter avec tout plein d&rsquo;autres
services…</p>
<hr>
<h2 id="dépannage">Dépannage</h2>
<h3 id="curl">curl</h3>
<p>curl se plaint… et me casse les pieds, par la même occasion.
Voici quelques pistes face à certaines erreurs :</p>
<h4 id="curl-35-error1400442essl-routinesconnect_cr_srvr_hellotlsv1-alert-protocol-version">curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version</h4>
<p>Êtes-vous sûr d&rsquo;avoir activer l&rsquo;option <code>https-enabled</code> dans la section <code>[http]</code> ?</p>
<p>Vérifiez !</p>
<h4 id="curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate">curl: (60) SSL certificate problem: unable to get local issuer certificate</h4>
<p>Comme le contexte d&rsquo;utilisation décrit dans ce guide de démarrage, vous
avez généré vos propres certificats sans utiliser d&rsquo;Autorité de Certification.</p>
<p>Ajoutez l&rsquo;option <code>-k</code> !</p>
<h3 id="influxdb">influxdb</h3>
<h4 id="unable-to-open-access-log-falling-back-to-stderr">unable to open access log, falling back to stderr</h4>
<p>Le message d&rsquo;erreur dans le log daemon est du type :<br>
<code>lvl=error msg=&quot;unable to open access log, falling back to stderr&quot; log_id=0eMCqvRl000 service=httpd error=&quot;open /var/log/influxdb/: is a directory&quot; path=/var/log/influxdb/</code></p>
<p>Le chemin spécifié dans la variable <code>access-log-path</code> est soit inexistant,
soit influxdb n&rsquo;a pas les droits systèmes pour y accéder.</p>
<p>Vérifiez !</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://docs.influxdata.com/influxdb/v1.8/administration/config/" rel="external">https://docs.influxdata.com/influxdb/v1.8/administration/config/</a></li>
<li><a href="https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/" rel="external">https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Guide de démarrage : Introduction à influxdb sur OpenBSD]]></summary>
        <published>2022-11-24T07:07:42+01:00</published>
        <updated>2025-11-11T15:44:28+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:deeadbd9-c6e9-ac3c-ae3f-f06b3fdf1b2a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/multimedia/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Gestion de l&#39;audio ET de la vidéo</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="mixerctl" scheme="http://doc.huc.fr.eu.org/fr/tags/mixerctl/" />
        <category term="sndiod" scheme="http://doc.huc.fr.eu.org/fr/tags/sndiod/" />
        <category term="sndioctl" scheme="http://doc.huc.fr.eu.org/fr/tags/sndioctl/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voyons ensemble comment gérer les fonctionnalités multimédias sous OpenBSD.</p>
<h2 id="audio">Audio</h2>
<h3 id="gestion-du-bip">Gestion du Bip</h3>
<p>Le bip sonore qui se fait entendre parfois dans certains contextes, tel
lors de l&rsquo;utilisation de la complétion de commande avec la touche <kbd>Tab</kbd>,
peut être rendu muet.</p>
<p>Avant OpenBSD 6.7, c&rsquo;est l&rsquo;outil <code>mixerctl</code> qui le permettait : <br>
<code>:# mixerctl inputs.mix_beep = 0</code></p>
<p>Depuis OpenBSD 6.7, ce paramètre est géré par le pilote <code>wscons(4)</code>
et configuré par le biais du contrôleur <code>wsconsctl(8)</code> — ce qui
nécessite des droits administrateurs.</p>
<p>Pour le rendre muet :
<code>:# wsconsctl keyboard.bell.volume=0</code></p>
<p>Pour le désactiver définitivement et garder le paramètre au redémarrage,
copiez-le fichier <code>/etc/examples/wsconsctl.conf</code> vers <code>/etc</code> et
décommentez la ligne : <code>#keyboard.bell.volume=0</code></p>
<h3 id="enregistrement-audio">Enregistrement audio</h3>
<p>Depuis OpenBSD 6.4, pour des raisons de confidentialité, l&rsquo;enregistrement
audio est désactivé. Pour le réactiver :</p>
<p><code>:# sysctl kern.audio.record=1</code></p>
<p>Pensez à modifier le fichier <code>/etc/sysctl.conf</code> !</p>
<p>Cela sera utile dans le contexte d&rsquo;utilisation d&rsquo;un microphone, d&rsquo;une
webcam ayant un micro, etc… ce qui permettra d&rsquo;utiliser correctement
tout logiciel tel audacity… ainsi que lors de l&rsquo;utilisation
du protocole <strong>WebRTC</strong> avec les navigateurs web, que sont Firefox et
Chromium.</p>
<h3 id="gestion-des-niveaux">Gestion des niveaux</h3>
<p>La gestion des niveaux de volume se fait en espace utilisateur, grâce à
l&rsquo;outil <strong>sndioctl(1)</strong>. Pas besoin de droits administrateur dans la session
utilisateur.</p>
<ul>
<li>pour augmenter/diminuer le niveau : <code>:$ sndioctl output.level=+0.1</code></li>
<li>pour mettre/enlever le mode muet : <code>:$ sndioctl output.mute=!</code></li>
<li>pour voir les niveaux en pourcentage :
<code>:$ sndioctl output.level | awk -F = '{printf &quot;%d\n&quot;,$2*100}'</code></li>
</ul>
<p>Pensez à modifier votre fichier <code>~/.kshrc</code> pour ajouter la commande
si vous voulez un niveau audio par défaut lors du démarrage de la session.</p>
<h3 id="gestion-des-paramètres">Gestion des paramètres</h3>
<p>Pour la gestion des paramètres, c&rsquo;est l&rsquo;outil <strong>mixerctl(1)</strong> qui est à
utiliser. Celui-ci s&rsquo;utilise toujours avec des droits administrateurs !</p>
<ul>
<li><code>:# mixerctl -av</code> permet de savoir ce qui de votre matériel est reconnu.</li>
</ul>
<p>Toute modification de paramètres devra être enregistré dans le fichier
<code>/etc/mixerctl.conf</code> qui n&rsquo;existe pas par défaut. Il faut le copier depuis
les fichiers d&rsquo;exemples : <br>
<code>:# cp /etc/examples/mixerctl.conf /etc/</code></p>
<p>Illustrons par le cas d&rsquo;utilisation d&rsquo;une sortie USB Audio et SPDIF :</p>
<h3 id="hdmi-audio">HDMI Audio</h3>
<p>C&rsquo;est apparemment une situation complexe qui semble n&rsquo;avoir encore à ce
jour pas de solution.</p>
<p>Pour comprendre le propos lire la discussion suivante et suivez le fil :
<a href="https://marc.info/?l=openbsd-tech&amp;m=158780750403100&amp;w=2" rel="external">https://marc.info/?l=openbsd-tech&m=158780750403100&w=2</a></p>
<h3 id="usb-audio">USB Audio</h3>
<h4 id="dac-usb">DAC USB</h4>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Cette sortie est considérée comme une sortie analogique. Par défaut, c&rsquo;est
le mode de sortie utilisé… si ce n&rsquo;est pas/plus le cas, reconfigurez-la : <br>
<code>outputs.mode=analog</code></div>

<p>Il est de plus en plus courant d&rsquo;avoir un périphérique Audio par USB, voir
un DAC Audio USB. Une fois connecté, pour vérifier son support, utilisons
la commande suivante : <br>
<code>dmesg | grep uaudio</code> ainsi que la commande <code>usbdevs</code>.</p>
<p>Tel que, pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>uaudio0 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Logitech Logitech USB Headset&#34;</span> rev 1.10/10.13 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uaudio0: class v1, full-speed, sync, channels: <span style="color:#f99b15">2</span> play, <span style="color:#f99b15">1</span> rec, <span style="color:#f99b15">7</span> ctls
</span></span><span style="display:flex;"><span>audio1 at uaudio0
</span></span></code></pre></div><p>qui est reconnu en tant que périphérique <code>uaudio0</code> qui est connecté sur
le périphérique spécial audio <code>audio1</code>.</p>
<p>Le serveur sndiod le reconnaît en tant que périphérique <code>snd/1</code>.</p>
<p>Deux manières différentes de procéder :</p>
<ul>
<li>la plus simple est de reconfigurer la variable <code>server.device</code> pour qu&rsquo;il
écoute le périphérique <code>snd/1</code> : <br>
<code>:$ sndioctl server.device=1</code> <br>
ce qui a pour avantage de ne pas avoir à reconfigurer tout autre logiciel
pour écouter ledit périphérique.</li>
<li>la deuxième est liée aux programmes gérant de l&rsquo;audio capables d&rsquo;utiliser
directement le périphérique <code>snd/1</code>.</li>
</ul>
<hr>
<p>Par exemple, avec le logiciel <strong>audacious</strong>, il faut aller dans les
<strong>Paramètres &gt; Paramètre de son</strong>, puis face au champ <strong>Greffon de sortie</strong>,
il y a deux boutons, dont l&rsquo;un nommé <strong>[Paramètres]</strong> qui ouvre une autre
fenêtre où pour le champ <strong>Périphérique :</strong>, il faudra écrire le nom du
périphérique audio USB, soit <code>snd/1</code>, puis valider et écouter du son…</p>
<hr>
<p>Il existe une manière alternative pour que le serveur sndiod reconnaisse
automatiquement le périphérique USB en tant que périphérique par défaut,
lorsqu&rsquo;il est connecté physiquement, puis de rebasculer sur le périphérique
<code>snd/0</code> dès que ce n&rsquo;est plus le cas.</p>
<p>Pour ce contexte, il faut redéfinir les drapeaux du serveur sndiod puis
le relancer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl set sndiod flags -f rsnd/0 -F rsnd/1
</span></span><span style="display:flex;"><span>:# rcctl restart sndiod
</span></span></code></pre></div><p>Le serveur n&rsquo;est pas capable de se relancer automatiquement si vous connectez
le périphérique USB après le (re)démarrage du serveur. Une fois, le périphérique
connecté, rechargez tout simplement le serveur : <br>
<code>:# rcctl reload sndiod</code>
forcera le serveur a détecter à nouveau le périphérique.</p>
<hr>
<p>Un autre outil disponible est l&rsquo;utilisation de la commande <code>usbhidaction</code>…</p>
<p>Je vous renvoie au manpage relatif — cf la section <a href="/fr/sys/openbsd/multimedia/#documentations">Documentations</a>.</p>
<h4 id="microphone-usb">Microphone USB</h4>
<p>⇒ Après avoir connecté physiquement votre microphone USB, vérifiez la reconnaissance :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ dmesg | grep audio
</span></span><span style="display:flex;"><span>uaudio0 at uhub4 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;BIRD UM1 BIRD UM1&#34;</span> rev 1.10/1.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uaudio0: class v1, full-speed, sync, channels: <span style="color:#f99b15">0</span> play, <span style="color:#f99b15">1</span> rec, <span style="color:#f99b15">2</span> ctls
</span></span><span style="display:flex;"><span>audio1 at uaudio0
</span></span></code></pre></div><p><em>(dans mon cas, le microphone est bien le <strong>BIRD UM1</strong>.)</em></p>
<p>Si vous avez une sortie similaire, alors votre microphone USB est bien
reconnu et sera utilisable ; si non, dommage.</p>
<p>Là encore du fait d&rsquo;être un périphérique USB, le serveur sndiod capture
l&rsquo;enregistrement micro en tant que périphérique <code>snd/1</code> principalement.</p>
<p>⇒ Pour utiliser le microphone USB sous OpenBSD :</p>
<ol>
<li>Dans un premier temps, veillez à activer l'
<a href="/fr/sys/openbsd/multimedia/#enregistrement-audio">enregistrement audio</a>.</li>
<li>Puis, il faut paramètrer le serveur sndiod, tel que : \</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl set sndiod flags -s default -m play,mon -s mon
</span></span></code></pre></div><ol start="3">
<li>puis le (re)démarrer…</li>
<li>Optionnellement, vous pouvez vous assurer des paramètres d&rsquo;entrée par
le contrôleur <strong>sndioctl</strong>, tel que :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ sndioctl input.mute<span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>:$ sndioctl input.level<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span></code></pre></div><hr>
<p>Un petit test de fonctionnement, en parlant près du microphone :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ aucat -f snd/1 -o output.wav
</span></span></code></pre></div><p>Et pour l&rsquo;écoute :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ aucat -i output.wav
</span></span></code></pre></div><h3 id="sortie-spdif">Sortie SPDIF</h3>
<p>Pour utiliser une sortie SPDIF, il faut modifier le mode de sortie ; en
effet, par défaut le mode de sortie correspond à l&rsquo;analogique.</p>
<p>Avec l&rsquo;outil <code>mixerctl</code>, modifiez ce mode, tel que : <br>
<code>outputs.mode=digital</code></p>
<p>Ensuite, il faut modifier le serveur de son <strong>sndiod(8)</strong> pour qu&rsquo;il gère
les canaux audio correspondants, car par défaut, il ne gère que les deux
premiers canaux, à savoir <code>0:1</code> ; ce qui permet d&rsquo;avoir quand même un son
stéréo.</p>
<p>Avant de le modifier, vérifions dans un premier temps, la sortie SPDIF,
tel que : <br>
<code>:# mixerctl outputs.SPDIF_source</code></p>
<p>Dans le contexte de la carte-mère que j&rsquo;utilise :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas mixerctl outputs.SPDIF_source
</span></span><span style="display:flex;"><span>outputs.SPDIF_source<span style="color:#5bc4bf">=</span>dig-dac-2:3
</span></span></code></pre></div><p>Ainsi, la sortie SPDIF se fait sur les canaux 2 et 3.</p>
<p>Modifions le serveur sndiod pour ajouter la gestion des canaux 2 et 3, au
démarrage de celui-ci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl set sndiod flags -c 0:3
</span></span><span style="display:flex;"><span>:# rcctl restart sndiod
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Il est possible de lui signifier de n&rsquo;utiliser que les canaux 2 et 3.</p>
<p>De plus, votre matériel peut certainement utiliser encore plus de canaux.
À vous de modifier en conséquence…</p>
<p>Lire le manpage <strong>sndiod(8)</strong> qui montre dans les exemples son utilisation
en espace utilisateur.</p>
</div>

<h2 id="vidéo">Vidéo</h2>
<h3 id="enregistrement-vidéo">Enregistrement vidéo</h3>
<p>Par défaut, depuis OpenBSD 6.9, pour des raisons de confidentialité,
l&rsquo;enregistrement vidéo est désactivé !</p>
<p>Pour le réactiver :</p>
<p><code>:# sysctl kern.video.record=1</code></p>
<p>Pensez à modifier le fichier <code>/etc/sysctl.conf</code> !</p>
<p>Cela sera utile dans le contexte d&rsquo;utilisation d&rsquo;une webcam ayant un micro,
etc… ce qui permettra d&rsquo;utiliser correctement tout logiciel tel fswebcam…
ainsi que lors de l&rsquo;utilisation du protocole <strong>WebRTC</strong> avec les navigateurs
web, que sont Firefox et Chromium.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="mixerctl-audio_mixer_write-device-busy">mixerctl: AUDIO_MIXER_WRITE: Device busy</h3>
<p>Lorsque vous essayez de changer le mode de sortie de l&rsquo;analogique vers le
digital et réciproquement, le système vous répond avec ce message interdisant
la modification.</p>
<ol>
<li>arrêtez d&rsquo;abord le serveur sndiod ; vérifiez qu&rsquo;il est correctement éteint.</li>
<li>refaites la modification désirée, avec l&rsquo;outil <code>mixerctl</code></li>
<li>redémarrez le serveur sndiod</li>
</ol>
<h3 id="vérifier-le-fonctionnement-du-serveur-sndiod">vérifier le fonctionnement du serveur sndiod</h3>
<p>Pour vérifier le fonctionnement du serveur sndiod(8), hormis de vérifier
le status de son démon, utilisez la commande suivante :
<code>:$ pgrep -lf sndiod</code></p>
<p>Par exemple</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ pgrep -lf sndiod
</span></span><span style="display:flex;"><span><span style="color:#f99b15">44982</span> /usr/bin/sndiod -c0:3
</span></span><span style="display:flex;"><span><span style="color:#f99b15">16091</span> sndiod: helper
</span></span></code></pre></div><p>qui montre le fonctionnement du serveur…</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://rsadowski.de/posts/2024-01-14-openbsd-video-audio-screen-recording/" rel="external">Effortless OpenBSD Audio and Desktop Screen Recording Guide</a></li>
</ul>
<h3 id="manpage">manpage</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/mixerctl" title="Page du Manuel OpenBSD pour : mixerctl">mixerctl</a>
, 
<a class="man" href="https://man.openbsd.org/sndioctl" title="Page du Manuel OpenBSD pour : sndioctl">sndioctl</a>
, 
<a class="man" href="https://man.openbsd.org/sndiod.8" title="Page du Manuel OpenBSD pour : sndiod">sndiod(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/usbhidaction" title="Page du Manuel OpenBSD pour : usbhidaction">usbhidaction</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/wscons.4" title="Page du Manuel OpenBSD pour : wscons">wscons(4)</a>
, 
<a class="man" href="https://man.openbsd.org/wsconsctl.8" title="Page du Manuel OpenBSD pour : wsconsctl">wsconsctl(8)</a>
</li>
</ul>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gestion du son, de la vidéo sous OpenBSD : USB Audio, sortie SPDIF, enregistrement audio et vidéo]]></summary>
        <published>2022-11-22T12:44:25+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a45795d2-03fa-9d35-4403-7d38342c070a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/obsdfreqd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: obsdfreqd : un service pour gérer la fréquence CPU / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="obsdfreqd" scheme="http://doc.huc.fr.eu.org/fr/tags/obsdfreqd/" />
        <category term="apm" scheme="http://doc.huc.fr.eu.org/fr/tags/apm/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>obsdfreqd</strong> est un service/démon permettant de gérer la fréquence de
votre CPU dans l&rsquo;espace utilisateur.</p>
<p>Beaucoup de paramètres permettent de configurer la fréquence tels que la
fréquence min/max, l&rsquo;inertie, etc. obsdfreqd supporte aussi la limitation
de la fréquence une fois qu&rsquo;une certaine température est atteinte afin
de protéger le système, en le faisant revenir sous le seuil. Bien qu&rsquo;il
y ait beaucoup de paramètres, ceux par défaut sont suffisamment bon pour
chacun.</p>
<ul>
<li>Auteure : Solène Rapenne</li>
<li>Dépôt git : <a href="https://git.sr.ht/~solene/obsdfreqd" rel="external">https://git.sr.ht/~solene/obsdfreqd</a></li>
<li>Disponible dans les ports officiellement depuis : OpenBSD 7.1</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Depuis OpenBSD 7.6, ce projet semble moins pertinent, puisque la variable <code>hw.perfpolicy</code>
géré par <strong>sysctl</strong> a été ajoutée au système, paramétrée par défaut sur la valeur
<code>auto</code>. <em>Cf le <a href="https://man.openbsd.org/sysctl.2#HW_PERFPOLICY~2" rel="external">manpage</a></em></div>

<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>obsdfreqd</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="démarrage-du-service">Démarrage du service</h3>
<p>Il est nécessaire :</p>
<ul>
<li>d&rsquo;<a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer le service</a>

<code>obsdfreqd</code>.</li>
<li>d&rsquo;<a class="inside" href="/fr/sys/openbsd/rcctl/#arr%c3%aater" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Arrêter le service</a>

<code><a class="inside" href="/fr/sys/openbsd/apm/" title="Lien interne vers l&#39;article : 'Apm : Programme de contrôle de la gestion de l&#39;énergie et de l&#39;hibernation'">apmd</a>
</code> s&rsquo;il est utilisé,</li>
<li>puis de le <a class="inside" href="/fr/sys/openbsd/rcctl/#param%c3%a9trer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">paramétrer</a>

pour l&rsquo;exécuter avec le drapeau <code>-L</code>.</li>
<li>et enfin de <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrer les services</a>

<code>obsdfreqd</code> et <code>apmd</code></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Note : Il est possible de ne pas utiliser le service <code>apmd</code> ; quoiqu&rsquo;il
en soit de par le fonctionnement du service d&rsquo;obsdfreqd, apmd doit être
exécuté en paramètre manuel qui mettra la fréquence CPU au minimum,
obsdfreqd prend le relais correctement.</p>
<p>Utiliser apmd en mode manuel est utile pour la gestion d’événements,
tels que la veille et l&rsquo;hibernation.</p>
</div>

<h2 id="utilisation">Utilisation</h2>
<p>Si besoin, il est possible de
<a class="inside" href="/fr/sys/openbsd/rcctl/#param%c3%a9trer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">paramétrer</a>

manuellement <strong>obsdfreqd</strong>.</p>
<p>Retrouvez les différentes options sur la page du projet : <br>
<a href="https://tildegit.org/solene/obsdfreqd/#usage" rel="external">https://tildegit.org/solene/obsdfreqd/#usage</a></p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>
<a class="" href="https://man.openbsd.org/sysctl.2#HW_PERFPOLICY~2" title="Page du Manuel OpenBSD pour : sysctl">sysctl(2)#HW_PERFPOLICY~2</a>
</li>
</ul>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer correctement les fréquences CPU grâce à l&#39;outil &#39;obsdfreqd&#39; sous OpenBSD]]></summary>
        <published>2022-11-19T12:28:54+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:bc8d27ba-fd2a-6fd1-ad7f-f9159f8f42fc</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/pass-gestionnaire-mot-passe-unix/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Pass : À la Découverte d&#39;un Gestionnaire de Mot de Passe</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="pass" scheme="http://doc.huc.fr.eu.org/fr/tags/pass/" />
        <category term="password" scheme="http://doc.huc.fr.eu.org/fr/tags/password/" />
        <category term="store" scheme="http://doc.huc.fr.eu.org/fr/tags/store/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><code>pass</code> est un gestionnaire de mot-de-passe, respectant la philosophie Unix,
qui se veut être simple. Et, pour d&rsquo;aucuns, il est CLI… mais pas que !<br></p>
<p>Des gestionnaires de mot-de-passe, il en existe pléthore ; pour n&rsquo;en citer
quelques uns, tel KeePass <em>(et ses déclinaisons)</em>, BitWarden, etc…</p>
<p>Comme beaucoup, c&rsquo;est plus un gestionnaire d&rsquo;identités et d&rsquo;informations
personnelles confidentielles qu&rsquo;un basique gestionnaire de mots de passe.<br>
En bref, c&rsquo;est un coffre fort numérique, en CLI, à la sauce GPG !</p>
<p>Qu&rsquo;a donc de <strong>SI</strong> particulier <strong>pass</strong> ?<br>
Il est :</p>
<ul>
<li>CLI</li>
<li>chiffré par GPG</li>
<li>simple à utiliser</li>
<li><em>(peut)</em> utilise(r) Git</li>
<li>mettre très temporairement en copie les infos dans le presse-papier.</li>
</ul>
<p>Mais encore ?<br>
Il fait de la complétion pour les shells suivants : <br></p>
<ul>
<li>Bash</li>
<li>fish</li>
<li>zsh</li>
</ul>
<p>Et pour finir, il a des extensions intéressantes, certaines pour
navigateurs web, et des clients GUI pour différentes plateformes.</p>
<ul>
<li>Licence : GNU/GPL v2</li>
<li>Site web: <a href="https://www.passwordstore.org" rel="external">https://www.passwordstore.org</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Installons le binaire et l&rsquo;interface graphique <em>— cette dernière n&rsquo;est pas
nécessaire, mais utile —</em> :</p>
<p>⇒ Debian/*Buntu <em>(et assimilés)</em> : <code>apt install pass qtpass</code></p>
<p>⇒ OpenBSD : <code>pkg_add password-store qtpass</code></p>
<h3 id="extensions">Extensions</h3>
<p>Parmi les extensions utiles, il y a :</p>
<ul>
<li>
<p><strong><a href="https://github.com/roddhjav/pass-import" rel="external">pass-import</a></strong> pour importer
depuis de nombreux autres gestionnaires de mot-de passes ;</p>
<ul>
<li>pour Debian/*Buntu, il faut l&rsquo;installer depuis le dépôt de
l&rsquo;auteur, <em>qui fournit un paquet .deb.</em></li>
<li>quant à OpenBSD, installable depuis les ports,</li>
</ul>
</li>
<li>
<p><strong><a href="https://github.com/palortoff/pass-extension-tail" rel="external">pass-extension-tail</a></strong>
pour afficher les informations secondaires, renfermées dans un des
fichiers chiffrés.</p>
<ul>
<li>pour Debian/*Buntu, depuis les dépôts officiels</li>
<li>pour OpenBSD, depuis le dépôt git, avec la cible <code>make install</code></li>
</ul>
</li>
<li>
<p><strong><a href="https://github.com/tadfisher/pass-otp#readme" rel="external">pass-otp</a></strong> qui ajoute
le support des tokens OTP.
<em>Dans le contexte de sécurité multi-facteurs, il vaut mieux utiliser
une autre application, qui sera elle seule responsable de cet aspect.</em></p>
<ul>
<li>pour Debian/*Buntu : <strong>pass-extension-otp</strong>, depuis les dépôts officiels</li>
<li>pour OpenBSD : <strong>pass-otp</strong>, depuis les ports</li>
</ul>
</li>
</ul>
<p>Il en existe quelques autres… <em>dont <strong><a href="https://github.com/roddhjav/pass-tomb#readme" rel="external">pass-tomb</a></strong>.</em></p>
<h3 id="clients-compatibles">Clients compatibles</h3>
<p>Parmi les clients compatibles actifs, il existe principalement :</p>
<ul>
<li>
<p><strong>qtpass</strong> : interface QT pour Linux, *BSD</p>
</li>
<li>
<p><strong><a href="https://github.com/android-password-store/Android-Password-Store" rel="external">Password Store</a></strong> :
pour Android, disponible, entre autres, sur F-Droid ; <em>à coupler avec
l&rsquo;app <strong>OpenKeychain</strong> pour gérer la clé GPG</em>.<br></p>
</li>
<li>
<p><strong>BrowserPass</strong> : un projet scindé en deux :</p>
<ul>
<li><a href="https://github.com/browserpass/browserpass-native" rel="external">Browserpass-native</a> :
une sorte de proxy pour communiquer entre le gestionnaire et l'
extension pour les navigateurs web.
<ul>
<li>Installable depuis les dépôts pour Debian/*Buntu, nommée <strong>webext-browserpass</strong>.</li>
<li>Quant à OpenBSD, il faudra la compiler localement avec la cible
<strong>make browserpass-openbsd64</strong>, après avoir téléchargé le dépôt.</li>
</ul>
</li>
<li><a href="https://github.com/browserpass/browserpass-extension" rel="external">Browserpass-extension</a> :
une extension pour les navigateurs Chrome et Firefox.<br>
<strong>Il n&rsquo;est pas recommandé d&rsquo;activer l&rsquo;option OTP pour des raisons
de sécurité, pour la raison sus-mentionnée</strong>.</li>
</ul>
</li>
<li>
<p><strong><a href="https://mssun.github.io/passforios/" rel="external">passforios</a></strong> : pour iOS</p>
</li>
<li>
<p>y&rsquo;en a même <a href="https://git.zx2c4.com/password-store/tree/contrib/emacs" rel="external">une</a>
pour les addicts emacs….</p>
</li>
</ul>
<p>Et certainement bien d&rsquo;autres…</p>
<h2 id="configuration">Configuration</h2>
<h3 id="extensions-1">Extensions</h3>
<p>Un fichier de configuration spécial <code>~/.password-store/.extensions/COMMAND.bash</code>
peut être créé afin d&rsquo;activer les extensions installées.</p>
<p>Il faut y ajouter :</p>
<ul>
<li><code>PASSWORD_STORE_ENABLE_EXTENSIONS=true</code> pour ajouter le support des extensions</li>
</ul>
<h3 id="variables-environnement">VARIABLES ENVIRONNEMENT</h3>
<p>Quelques variables d&rsquo;environnement utiles :</p>
<ul>
<li>
<p><code>PASSWORD_STORE_DIR</code> définit le répertoire par défaut du gestionnaire</p>
</li>
<li>
<p><code>PASSWORD_STORE_EXTENSIONS_DIR</code> définit le répertoire des fichiers
d&rsquo;extension ; par défaut <code>PASSWORD_STORE_DIR/.extensions</code>.</p>
</li>
<li>
<p><code>PASSWORD_STORE_CLIP_TIME</code> est le nombre de secondes de rétention dans
le presse-papier, par défaut de <strong>45 secondes</strong>.</p>
</li>
<li>
<p><code>PASSWORD_STORE_GENERATED_LENGTH</code> est la longueur en nombre de caractères
du mot de passe à utiliser par défaut pour l&rsquo;option <code>generate</code>.</p>
</li>
<li>
<p><code>PASSWORD_STORE_GPG_OPTS</code> afin de passer des options à GPG.</p>
</li>
<li>
<p><code>EDITOR</code> sera l&rsquo;éditeur texte utilisé par l&rsquo;option <code>edit</code>.</p>
</li>
</ul>
<p>Et à coup sûr, d&rsquo;autres…</p>
<h3 id="gpg-agentconf">gpg-agent.conf</h3>
<p>Il peut être utile, surtout en rapport avec l&rsquo;extension <strong>Browserpass</strong>,
d&rsquo;éditer le fichier <code>~/.gnupg/gpg-agent.conf</code> pour ajouter la gestion de
la saisie correcte des mots de passe par l&rsquo;outil <strong>pinentry</strong>, tel que :</p>
<ul>
<li>
<p><code>pinentry-program /usr/bin/pinentry-gtk-2</code> pour un bureau utilisant
les bibliothèques Gtk2, tel Cinnamon, Gnome 2, Mate, Xfce, …</p>
</li>
<li>
<p><code>pinentry-program /usr/bin/pinentry-gnome3</code>, pour Gnome 3, Xfce, …</p>
</li>
<li>
<p><code>pinentry-program /usr/bin/pinentry-x11</code> pour tout autre bureau sous
environnement X11, tel Enlightenment, LXDE, LXQt, dwm, …</p>
</li>
<li>
<p>voire <code>pinentry-program /usr/bin/pinentry</code> ou son équivalent <code>/usr/bin/pinentry-curses</code>
si vous ne fonctionnez qu&rsquo;en environnement terminal.</p>
</li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<p>Bien que le site soit descriptif quant à son installation et utilisation,
ainsi que le <a href="https://git.zx2c4.com/password-store/about/" rel="external">man page</a>,
voyons ensemble quelques étapes intéressantes :</p>
<p>⇒ L&rsquo;usage de la commande <code>pass</code> sans aucune option affiche le contenu
de l&rsquo;arborescence tel que créé, par vos soins. Pour l&rsquo;instant, il est vide.</p>
<hr>
<h3 id="initialisation">Initialisation</h3>
<p>L&rsquo;initialisation du gestionnaire se fait localement et est liée à une clé
GPG créée précédemment, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass init email@domain.tld
</span></span><span style="display:flex;"><span>mkdir: created directory ‘/home/your-user/.password-store’
</span></span><span style="display:flex;"><span>Password store initialized <span style="color:#815ba4">for</span> email@domain.tld.
</span></span></code></pre></div><p>Il est important de comprendre que l&rsquo;initialisation puis l&rsquo;ouverture du
gestionnaire demandera obligatoirement le mot de passe liée à la clé GPG.</p>
<h3 id="gestion-du-dépôt-git">Gestion du dépôt git</h3>
<p>En second, vient la phase du dépôt local git :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass git init
</span></span><span style="display:flex;"><span>Initialized empty Git repository in /home/your-user/.password-store/.git/
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>master <span style="color:#5bc4bf">(</span>root-commit<span style="color:#5bc4bf">)</span> 998c8fd<span style="color:#5bc4bf">]</span> Added current contents of password store.
</span></span><span style="display:flex;"><span><span style="color:#f99b15">1</span> file changed, <span style="color:#f99b15">1</span> insertion<span style="color:#5bc4bf">(</span>+<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>create mode <span style="color:#f99b15">100644</span> .gpg-id
</span></span></code></pre></div><p>Il crée localement le fichier <code>.gpg-id</code> qui renferme l&rsquo;identifiant long
de l&rsquo;empreinte de la clé GPG.</p>
<hr>
<p>⇒ Ajout du dépôt extérieur</p>
<p>Ensuite ajouter un dépôt Git extérieur <em>— ceci sera utile pour la
réplication des données au-travers des différents GUI disponibles,
sur d&rsquo;autres OS —</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass git remote add origin URL-depot-git
</span></span></code></pre></div><hr>
<p>⇒ Ajout des signatures GPG</p>
<p>De plus, il est fortement recommandé d&rsquo;ajouter le support des signatures
GPG :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass git config --bool --add pass.signcommits true
</span></span></code></pre></div><p>Chaque commit nécessitera ainsi l&rsquo;usage d&rsquo;une clé GPG pour confirmer que
vous êtes bien l&rsquo;auteur de la modification. <em>La Clé GPG peut très bien
être différente de celle liée au gestionnaire pass. Elle est liée à la
configuration du dépôt extérieur.</em></p>
<hr>
<p>⇒ À-propos de Git :</p>
<p>Les options de Git sont utilisables en argument de l&rsquo;option <code>git</code> exactement
à l&rsquo;identique de l&rsquo;outil Git.</p>
<ul>
<li>Pour pousser un ou plusieurs commits vers le dépôt extérieur : <code>pass git push</code>, à minima.</li>
<li>Pour récupérer depuis le dépôt extérieur : <code>pass git pull</code>…</li>
<li>etc.</li>
</ul>
<p>Du fait d&rsquo;avoir initié le dépôt local git, chaque création, la moindre
modification, d&rsquo;un fichier chiffré générera automatiquement un commit. <br>
Si vous utilisez la signature GPG de commit, il vous sera demandé le mot
de passe lié à la clé GPG pour les commits… <em>qui, pour rappel, peut très
bien être différente de la clé GPG du gestionnaire pass</em>.</p>
<h3 id="gestion-des-fichiers-chiffrés">Gestion des fichiers chiffrés</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Après un certain délai, relativement court : 45 sec., même la consultation
d&rsquo;un fichier chiffré provoquera un appel du mot de passe lié à la clé GPG
relative au gestionnaire pass. Ne soyez pas étonné que cela vous soit
régulièrement demandé.</p>
<hr>
<p><strong>Conventions d&rsquo;écriture :</strong></p>
<ul>
<li><strong>La première ligne</strong> d&rsquo;un fichier chiffré est <strong>toujours le mot-de-passe</strong> !</li>
<li><strong>La deuxième ligne</strong> peut servir à entrer l&rsquo;identifiant lié au mot-de-passe, autrement
dit le <strong>login</strong></li>
<li><strong>La troisième ligne</strong> peut servir à entrer l&rsquo;<strong>URL</strong> correspondante, s&rsquo;il y a lieu…</li>
<li>d&rsquo;autres lignes… d&rsquo;autres informations utiles, pertinentes, etc.</li>
</ul>
<p>C&rsquo;est une convention utile à respecter… mais par défaut, étant donné que c&rsquo;est
un simple fichier texte chiffré, pass n&rsquo;impose aucun schéma ou type d&rsquo;organisation.
Si ce n&rsquo;est qu&rsquo;il est préférable d&rsquo;avoir en première ligne l&rsquo;écriture du
mot de passe, car c&rsquo;est son mode opératoire, et là où toute extension,
tout client cherchera cette information précise.</p>
<p>Merci de lire le man page pour avoir d&rsquo;autres notions de conventions.</p>
</div>

<p>⇒ Création</p>
<p>Créons notre premier fichier chiffré nommé <strong>test</strong>, à l&rsquo;aide de
l&rsquo;option <code>insert</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass insert test
</span></span><span style="display:flex;"><span>Enter password <span style="color:#815ba4">for</span> test:
</span></span><span style="display:flex;"><span>Retype password <span style="color:#815ba4">for</span> test:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>master 53331b0<span style="color:#5bc4bf">]</span> Add given password <span style="color:#815ba4">for</span> test to store.
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">1</span> file changed, <span style="color:#f99b15">0</span> insertions<span style="color:#5bc4bf">(</span>+<span style="color:#5bc4bf">)</span>, <span style="color:#f99b15">0</span> deletions<span style="color:#5bc4bf">(</span>-<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span> create mode <span style="color:#f99b15">100644</span> test.gpg
</span></span></code></pre></div><p>Lors de la création, il est demandé de taper un mot de passe, puis de le
ré-écrire une deuxième fois, puis un commit est généré.</p>
<p>Cette option permet de définir par ses propres soins un mot-de-passe.</p>
<p>L&rsquo;utilisation de l&rsquo;argument <code>-m</code> permet l&rsquo;ajout d&rsquo;autres informations, en
mode multilignes. Il faudra presser la combinaison de touches <kbd>CTRL+D</kbd>
pour sortir de ce mode d&rsquo;édition.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : l&rsquo;utilisation de cette option sur un fichier chiffré aura pour
conséquence de vider toute information existante. Il sera demandé de confirmer
avant ; en cas de refus de votre part, l&rsquo;action cessera.</div>

<p>⇒ Édition</p>
<p>L&rsquo;édition de tout fichier chiffré se fait avec l&rsquo;option <code>edit</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass edit test
</span></span></code></pre></div><p>Ce qui aura pour propos d&rsquo;ouvrir l&rsquo;éditeur de texte lié à votre environnement
ou par défaut <code>vi</code>, si aucun n&rsquo;est configuré. <em>Là, encore pour les amoureux
d&rsquo;emacs, installez l&rsquo;extension correspondante.</em></p>
<p>Il est ainsi possible de modifier toute information dans le fichier chiffré,
dont le mot de passe, lisible en clair.</p>
<p>⇒ Génération d&rsquo;un mot de passe</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : À moins d&rsquo;utiliser l&rsquo;argument <code>-i</code>, l&rsquo;utilisation de cette option
sur un fichier chiffré aura pour conséquence de vider toute information
existante. Il sera demandé de confirmer avant ; en cas de refus de votre
part, l&rsquo;action cessera.</div>

<p>La génération d&rsquo;un nouveau mot-de-passe pour un fichier chiffré se fait
par le biais de l&rsquo;option <code>generate</code>, suivi du nom de fichier chiffré et
d&rsquo;un chiffre représentant la longueur du mot de passe désiré :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass generate test <span style="color:#f99b15">32</span>
</span></span><span style="display:flex;"><span>An entry already exists <span style="color:#815ba4">for</span> test. Overwrite it? <span style="color:#5bc4bf">[</span>y/N<span style="color:#5bc4bf">]</span> y
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>master 5195534<span style="color:#5bc4bf">]</span> Add generated password <span style="color:#815ba4">for</span> test.
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">1</span> file changed, <span style="color:#f99b15">0</span> insertions<span style="color:#5bc4bf">(</span>+<span style="color:#5bc4bf">)</span>, <span style="color:#f99b15">0</span> deletions<span style="color:#5bc4bf">(</span>-<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>The generated password <span style="color:#815ba4">for</span> test is:
</span></span><span style="display:flex;"><span>zJwz<span style="color:#f99b15">\1</span>E<span style="color:#5bc4bf">(</span>RjL3Ps<span style="color:#5bc4bf">{</span>&amp;7|?QZAt<span style="color:#5bc4bf">{</span>&amp;ps_A_GU
</span></span></code></pre></div><ul>
<li>Pour générer un mot-de-passe avec juste des lettres et des chiffres, dit
alphanumérique, c&rsquo;est l&rsquo;argument <code>-n</code> qu&rsquo;il faut ajouter, tel que :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass generate -n test <span style="color:#f99b15">64</span>
</span></span><span style="display:flex;"><span>An entry already exists <span style="color:#815ba4">for</span> test. Overwrite it? <span style="color:#5bc4bf">[</span>y/N<span style="color:#5bc4bf">]</span> y
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>master 6dff2bd<span style="color:#5bc4bf">]</span> Add generated password <span style="color:#815ba4">for</span> test.
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">1</span> file changed, <span style="color:#f99b15">0</span> insertions<span style="color:#5bc4bf">(</span>+<span style="color:#5bc4bf">)</span>, <span style="color:#f99b15">0</span> deletions<span style="color:#5bc4bf">(</span>-<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>The generated password <span style="color:#815ba4">for</span> test is:
</span></span><span style="display:flex;"><span>EWA0SlCkzcmlMgxMWJltGnHCMSxK4YXmPYg4X3BrNryJgoUREVVFaaOXSiKijbtm
</span></span></code></pre></div><p>L&rsquo;option <code>generate</code> utilise le périphérique spécial <code>/dev/urandom</code> pour
générer le mot-de passe.</p>
<hr>
<ul>
<li>
<p>L&rsquo;argument <code>-c</code> copiera le mot de passe généré dans le presse-papier sans
l&rsquo;afficher.</p>
</li>
<li>
<p>L&rsquo;argument <code>-i</code> est pertinent pour ne pas détruire les informations contenues
dans le fichier chiffré, tout en créant un nouveau mot de passe, tel que :</p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass generate -i test <span style="color:#f99b15">32</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>master 25f75ab<span style="color:#5bc4bf">]</span> Replace generated password <span style="color:#815ba4">for</span> test.
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">1</span> file changed, <span style="color:#f99b15">0</span> insertions<span style="color:#5bc4bf">(</span>+<span style="color:#5bc4bf">)</span>, <span style="color:#f99b15">0</span> deletions<span style="color:#5bc4bf">(</span>-<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>The generated password <span style="color:#815ba4">for</span> test is:
</span></span><span style="display:flex;"><span>FrCL98OE9C9*7bJusLVbw$%<span style="color:#f99b15">\@</span>Y^<span style="color:#5bc4bf">[</span>,|Lj
</span></span></code></pre></div><p>⇒ Voir le contenu</p>
<p>Pour voir le contenu d&rsquo;un fichier chiffré, il suffit de l&rsquo;appeler directement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass test
</span></span><span style="display:flex;"><span>EWA0SlCkzcmlMgxMWJltGnHCMSxK4YXmPYg4X3BrNryJgoUREVVFaaOXSiKijbtm
</span></span><span style="display:flex;"><span>login: test@gmail.com
</span></span><span style="display:flex;"><span>URL: https://test-moi.tld
</span></span><span style="display:flex;"><span>comments: Ceci est un faux compte pour test du gestionnaire <span style="color:#48b685">`</span>pass<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>Merci de l<span style="color:#ef6155">&#39;</span>utiliser...
</span></span><span style="display:flex;"><span>PIN: <span style="color:#f99b15">123789654</span>
</span></span></code></pre></div><p><em>Les informations secondaires affichées dans cet exemple sont des ajouts
par mes soins, grâce à l&rsquo;option <code>edit</code>.</em></p>
<p>⇒ Trouver un contenu</p>
<p>Pour (re)trouver un contenu, c&rsquo;est l&rsquo;option <code>find</code> qui est à utiliser.</p>
<p>⇒ Copie et presse-papier</p>
<p>Pour copier dans le presse-papier, sachant qu&rsquo;en suivant la convention de
la première ligne comme étant le mot de passe :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass -c test
</span></span><span style="display:flex;"><span>Copied test to clipboard. Will clear in <span style="color:#f99b15">45</span> seconds.
</span></span></code></pre></div><p>Reste plus qu&rsquo;à le coller où nécessaire.</p>
<p>Pour copier, selon la convention décrite ci-dessus, l&rsquo;identifiant lié :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass -c2 test
</span></span><span style="display:flex;"><span>Copied test to clipboard. Will clear in <span style="color:#f99b15">45</span> seconds.
</span></span></code></pre></div><p>Etc.</p>
<p>⇒ Suppression</p>
<p>La suppression d&rsquo;un fichier chiffré est très simple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pass rm test
</span></span><span style="display:flex;"><span>rm: remove regular file ‘/home/your-user/.password-store/test.gpg’? y
</span></span><span style="display:flex;"><span>removed ‘/home/your-user/.password-store/test.gpg’
</span></span></code></pre></div><hr>
<p>Il existe quelques autres options ; je vous laisse les découvrir dans le
man page, telles <code>cp</code>, <code>ls</code> ou l&rsquo;usage de <code>grep</code>, etc.</p>
<h3 id="otp">OTP</h3>
<p>La fonction OTP fonctionne bien, à partir du moment où l&rsquo;on importe des
données depuis une autre source, grâce à l&rsquo;extension <strong>pass-import</strong>.</p>
<p>En CLI, je ne suis pas arriver à utiliser <strong>pass-otp</strong> ; j&rsquo;ai beau
eu faire <code>pass otp nom_fichier</code>, impossible ; alors qu&rsquo;avec <strong>qtpass</strong>
et <strong>Password Store</strong>, cela fonctionne.</p>
<h3 id="qtpass">qtpass</h3>
<p>Bien-sûr, tout cela se gère aussi au-travers de l&rsquo;interface graphique <strong>qtpass</strong>.</p>
<p>L&rsquo;application graphique <strong>qtpass</strong> est intéressante car elle permet de
définir dans son onglet &ldquo;Paramètres&rdquo; :</p>
<ul>
<li>le comportement du presse-papier</li>
<li>la longueur par défaut du mot-de-passe</li>
<li>d&rsquo;utiliser <code>pwgen</code> pour générer le mot-de-passe, et exclure ou non les
lettres en majuscule, les nombres, les autres symboles, tels les caractères
accentués, de générer des mots de passe facile à mémoriser</li>
<li>d&rsquo;utiliser git pour pousser automatiquement les push, les pulls, ajouter
la ou les clés GPG à gérer.</li>
</ul>
<p>⇒ Dans son onglet &ldquo;Programs&rdquo;, d&rsquo;utiliser soit l&rsquo;outil pass, soit les outils
natifs que sont Git et GPG…</p>
<p>⇒ De créer des profils de gestionnaire différents depuis l&rsquo;onglet &ldquo;Profiles&rdquo;.</p>
<p>⇒ De créer des modèles d&rsquo;affichage de l&rsquo;information pour les fichiers
chiffrés, depuis l&rsquo;onglet &ldquo;Templates&rdquo;.</p>
<h3 id="password-store--openkeychain">Password Store &amp; OpenKeychain</h3>
<p>L&rsquo;app <strong>Password Store</strong> nécessite l&rsquo;app <strong>OpenKeychain</strong>, toutes deux
installables depuis le store F-Droid.</p>
<p><strong>OpenKeychain</strong> sert à stocker une ou plusieurs clés GPG.</p>
<p>Pour utiliser votre clé GPG dans votre smartphone, il vaut mieux se prémunir
de quelques précautions suivantes :</p>
<ol>
<li>Génération d&rsquo;un mot de passe aléatoire fort avec GPG, sur la station :<br>
<code>gpg --armor --gen-random 1 20</code></li>
<li>Chiffrement de la clé GPG dans la station, en utilisant le mot de passe
généré par GPG :<br>
<code>gpg --armor --export-secret-keys &quot;GPG-Fingerprint-long&quot; | gpg --armor --symmetric --output mykey.sec.asc</code></li>
<li>Transfert vers le smartphone, connecté en USB, ou par le biais d&rsquo;une
carte SD.</li>
<li>Import dans OpenKeychain depuis le menu &lsquo;Importer ma clé&rsquo; qui demandera
à nouveau le mot de passe généré à l&rsquo;étape 1, et créera un fichier
nommé <code>decrypted.key</code> qu&rsquo;il faudra importer lui aussi dans OpenKeychain.</li>
</ol>
<h3 id="browserpass">Browserpass</h3>
<p>L&rsquo;extension <strong>Browserpass</strong> pour les navigateurs web Chrome et Firefox est
simple à utiliser. Pour un site web donné, elle va chercher les occurrences
dans le gestionnaire <strong>pass</strong>. Elle va automatiquement cibler le site web
dont la page est ouverte.</p>
<ul>
<li>L&rsquo;utilisation de la combinaison des touches <kbd>CTRL+Shift+L</kbd> permet
de rechercher les occurrences nécessaires, en lieu et place d&rsquo;un clic
sur l&rsquo;icône.</li>
<li>La touche <kbd>TAB</kbd> permet de naviguer entre les différents occurrences
trouvées.</li>
<li>Appuyer sur la touche <kbd>ENTRÉE</kbd> aura pour conséquence de remplir
automatiquement, valider la soumission d&rsquo;un formulaire de connexion.</li>
</ul>
<hr>
<h3 id="cas-dusage">Cas d&rsquo;usage</h3>
<ol>
<li>Création d&rsquo;un nouveau fichier chiffré, et/ou modification, soit en CLI
avec pass, soit avec la GUI qtpass.</li>
<li>git push, avec des commits signés, en SSH vers le dépôt GIT extérieur.</li>
<li>import dans Password Store, depuis le dépôt Git extérieur, par HTTPS</li>
<li>utilisation des extensions Browserpass pour la connexion à différents
sites web</li>
<li>utilisation d&rsquo;OTP, soit au-travers d&rsquo;une application tierce, soit après
import. <em>Personnellement, je préfère l&rsquo;app tierce</em>.</li>
</ol>
<p>Voilà un gestionnaire de mot de passe, totalement chiffré, par clé GPG,
dont les changements de chaque fichier .gpg sont versionnés par le biais
de Git, encapsulés soit dans une connexion SSH ou TLS selon l&rsquo;usage.</p>
<p>Chaque usage, que ce soit de la consultation ou de la modification, quelque
soit l&rsquo;outil utilisé, en CLI, par GUI, par une extension ou une autre,
telle l&rsquo;extension Browserpass, nécessite absolument l&rsquo;authentification GPG.</p>
<p>Voilà pour la découverte, assez complète, de ce gestionnaire de mot de passe,
voire d&rsquo;informations personnelles… pardon, que dis-je, de ce coffre fort
numérique différent.</p>
<h2 id="documentation">Documentation</h2>
<h3 id="interne">Interne</h3>
<ul>
<li><a class="inside" href="/fr/sec/gpg/gpg-ed25519/" title="Lien interne vers l&#39;article : 'GPG : Création de clé à Courbes Elliptiques Ed25519'">GPG : Création de clé à Courbes Elliptiques Ed25519</a></li>
<li><a class="inside" href="/fr/sec/gpg/gpg-usage-securise/" title="Lien interne vers l&#39;article : 'GPG : Du bon usage sécurisé'">GPG : Du bon usage sécurisé</a></li>
</ul>
<h3 id="wikipedia">Wikipedia</h3>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Philosophie_d%27Unix" title="Article Wikipédia : Philosophie_d&#39;Unix">Philosophie_d'Unix <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Découverte du coffre fort numérique, gestionnaire de mot-de-passe unix, d&#39;informations personnelles, qu&#39;est &#39;pass&#39;.]]></summary>
        <published>2022-10-25T17:05:45+02:00</published>
        <updated>2025-08-31T16:29:58+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:bc29d0c6-cdf6-d8ed-b560-2a833ed0a91f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/wifi-schedule/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Wifi Schedule - une méthode d&#39;économie d&#39;énergie</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="Wifi" scheme="http://doc.huc.fr.eu.org/fr/tags/wifi/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Comment faire de petites économies d&rsquo;énergie sous OpenWRT : éteindre et
activer les puces Wifi à heures programmées !</p>
<h2 id="installation">Installation</h2>
<p>Très simplement, dans un premier temps, il faut installer les deux modules
suivants <strong>wifischedule</strong> et <strong>luci-app-wifischedule</strong>.</p>
<p>En mode CLI: <br>
<code>opkg install wifischedule luci-app-wifischedule</code></p>
<p>Avec l&rsquo;interface web LuCI, allez dans la section &lsquo;System&rsquo; &gt; &lsquo;Software&rsquo;.</p>
<h2 id="configuration">Configuration</h2>
<p>Une fois installés, un nouveau menu est disponible depuis l&rsquo;interface LuCI,
dans &lsquo;Services&rsquo; &gt; &lsquo;Wifi Schedule&rsquo;.</p>
<p>Cette section propose 3 onglets, positionné par défaut sur &lsquo;Schedule&rsquo;.</p>
<ul>
<li>l&rsquo;onglet &lsquo;View Logfile&rsquo; permettra de voir le journal lié au fonctionnement
du service</li>
<li>l&rsquo;onglet &lsquo;View Cron Jobs&rsquo; affichera la table des tâches cron liés aux
événements programmés.</li>
</ul>
<h3 id="manual-control">Manual control</h3>
<p>Vous y trouverez tout particulièrement trois boutons :</p>
<ul>
<li>le premier [ ACTIVATE WIFI ] pour (ré?)activer le wifi, si besoin</li>
<li>le second [ DISABLE WIFI GRACEFULLY ] qui permet de désactiver le Wifi
de manière dite &ldquo;gracieuse&rdquo;, permettant aux périphériques connectés
d&rsquo;être déconnnecté une fois la session Wifi terminée.</li>
<li>le troisième [ DISABLE WIFI FORCE ] qui coupera le wifi immédiatement,
&ldquo;brutalement&rdquo;.</li>
</ul>
<h3 id="global-settings">Global Settings</h3>
<p>Pour activer le programmateur, cliquez sur la case à cocher : &lsquo;Enable Wifi Schedule&rsquo;,
dans la section &lsquo;Global Settings&rsquo;.</p>
<hr>
<p>Il est possible d&rsquo;utiliser la commande <code>uci</code>, tel que :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci set wifi_schedule.@global[0].enabled=&#39;1&#39;
</code></pre><hr>
<p>Vous trouverez aussi une option pour journaliser l&rsquo;activité <code>Enable logging</code>.</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci set wifi_schedule.@global[0].logging=&#39;1&#39;
</code></pre><h3 id="schedule-events">Schedule events</h3>
<p>Dans la section &lsquo;Schedule events&rsquo;, par défaut, deux programmations sont
déjà paramétrées :</p>
<ul>
<li>une première pour les journées de la semaine,</li>
<li>une autre pour celles du week-end.</li>
</ul>
<p>Une case à cocher &lsquo;Enable&rsquo; à activer ou non pour chacun des paramétrages,
avec les jours prédéfinis, ainsi que des horaires. Bin-sûr, tous ces paramétrages
par défaut peuvent être changés.</p>
<p>Il est même possible de forcer l&rsquo;extinction de la connexion des périphériques
en cochant la case &lsquo;Force disabling wifi even if stations associated&rsquo;.</p>
<p>En fin de section, un champ vide avec un bouton [ ADD ] pour ajouter de
nouveaux paramétrages.</p>
<p>Une fois les paramètres choisis, reste plus qu&rsquo;à cliquer sur le bouton
[ SAVE &amp; APPLY ].</p>
<hr>
<p>Voici pour exemple la configuration par défaut par le biais de la commande <code>uci</code> :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# uci show wifi_schedule
wifi_schedule.@global[0]=global
wifi_schedule.@global[0].logging=&#39;0&#39;
wifi_schedule.@global[0].enabled=&#39;1&#39;
wifi_schedule.@global[0].recheck_interval=&#39;10&#39;
wifi_schedule.@global[0].modules_retries=&#39;10&#39;
wifi_schedule.@global[0].unload_modules=&#39;0&#39;
wifi_schedule.Businesshours=entry
wifi_schedule.Businesshours.enabled=&#39;0&#39;
wifi_schedule.Businesshours.daysofweek=&#39;Monday Tuesday Wednesday Thursday Friday&#39;
wifi_schedule.Businesshours.starttime=&#39;06:00&#39;
wifi_schedule.Businesshours.stoptime=&#39;22:00&#39;
wifi_schedule.Businesshours.forcewifidown=&#39;0&#39;
wifi_schedule.Weekend=entry
wifi_schedule.Weekend.enabled=&#39;0&#39;
wifi_schedule.Weekend.daysofweek=&#39;Saturday Sunday&#39;
wifi_schedule.Weekend.starttime=&#39;09:00&#39;
wifi_schedule.Weekend.stoptime=&#39;23:30&#39;
wifi_schedule.Weekend.forcewifidown=0&#39;
</code></pre><p>Pour ajouter une entrée avec <code>uci</code>, par exemple :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">uci set wifi_schedule.Vacances=entry
uci set wifi_schedule.Vacances.enabled=&#39;1&#39;
uci set wifi_schedule.Vacances.daysofweek=&#39;Monday Tuesday Wednesday Thursday Friday Saturday Sunday&#39;
uci set wifi_schedule.Vacances.starttime=&#39;09:00&#39;
uci set wifi_schedule.Vacances.stoptime=&#39;23:30&#39;
uci set wifi_schedule.Vacances.forcewifidown=&#39;1&#39;
uci commit
</code></pre><p><em>Cet exemple crée une nouvelle entrée nommée &lsquo;Vacances&rsquo;, qui est activé, qui
a lieu tous les jours de la semaine, démarrant à 9h00 du matin, se coupant à
23h30, et qui a pour commande de forcer l&rsquo;arrêt des connexions wifi à l&rsquo;heure
d&rsquo;arrêt !</em></p>
<h2 id="wireless">Wireless</h2>
<p>Maintenant la consultation du menu &lsquo;Network&rsquo; &gt; &lsquo;Wireless&rsquo; aura pour propos
de montrer le wifi actif aux périodes d&rsquo;activité programmés, ou d&rsquo;être
pleinement désactivés lors des périodes d&rsquo;extinction programmés, tel que
la capture d&rsquo;écran ci-dessous :</p>
<figure>
    <a href="/images/openwrt/Network-Wireless-disabled.png" title="Aperçu de la fonction Wireless désactivée">
    <picture>
        
        <source srcset="/images/openwrt/Network-Wireless-disabled_hu_7ebc192fff8bf945.webp" type="image/webp">
        
        <img alt="Aperçu de la fonction Wireless désactivée" height="88" loading="lazy" src="/images/openwrt/Network-Wireless-disabled_hu_97737d54ccf1e84b.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Aperçu de la fonction Wireless désactivée</figcaption>
</figure>
<h2 id="eod">EOD</h2>
<p>Voilà, comment vous pouvez éteindre la ou les puce(s) Wifi de votre routeur
OpenWRT.</p>
<p>Il est possible de le faire en mode CLI de manière plus basique, sans cet
outil… mais avouez qu&rsquo;il est bien pratique.</p>
<p>EOD - Fin de Documentation</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[OpenWRT : programmer l&#39;arrêt et le redémarrage du Wifi]]></summary>
        <published>2022-10-22T09:28:23+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4216ab91-3d59-ce89-faf7-39338aa1ff88</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/openbsd-nsd-dnssec-tlsa/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Gérer DNS, DNSSEC (puis automatiser ses enregistrements TLSA)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DANE" scheme="http://doc.huc.fr.eu.org/fr/tags/dane/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="TLSA" scheme="http://doc.huc.fr.eu.org/fr/tags/tlsa/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>En 2018, je me suis posé la question de la gestion des enregistrements
TLSA, selon le protocole DANE, lié au protocole de sécurité DNSSEC,
dans mes zones DNS. <em>(cf: <a class="inside" href="/fr/post/generer-enregistrement-tlsa/" title="Lien interne vers l&#39;article : 'DNS: Générer un enregistrement TLSA'">DNS: Générer un enregistrement TLSA</a>) - je vous invite à le lire…</em></p>
<p><em>Certains vont utiliser l&rsquo;outil <strong>knot</strong>, fourni en tant que paquet sous
OpenBSD, car ils trouvent complexe à gérer. Mais nous verrons avec un
peu d&rsquo;astuces comment gérer cela de manière automatisé en shell,
sous OpenBSD</em>.</p>
<p>Pour rappel, mon service DNS fonctionne depuis plus de 4 ans, sous OpenBSD
grâce au logiciel natif <strong>nsd</strong>. La gestion des enregistrements
DNSSEC se fait grâce aux outils <strong><a href="https://openports.pl/path/net/ldns,-utils" rel="external">ldns</a></strong>
à installer en tant que paquet tiers.
J&rsquo;utilise dans les faits l&rsquo;outil <strong><a href="https://www.22decembre.eu/fr/2017/11/01/ldnscripts/" rel="external">ldnscript</a></strong>
qui permet de gérer la création des clés nécessaires puis s&rsquo;occupe de gérer
les enregistrements DNSSEC adéquats.</p>
<p>⇒ En Juin 2022, j&rsquo;ai décidé de basculer du chiffrement RSA par l&rsquo;utilisation
de l&rsquo;algorithme à courbes elliptiques nommés ECDSA.</p>
<p>Avant d&rsquo;aller plus loin en ce sens, passons à l&rsquo;installation des prérequis
nécessaires :</p>
<h2 id="installation">Installation</h2>
<h3 id="ldnscript">ldnscript</h3>
<p>Pour me rappeler comment faire, je me suis fait le petit mémo suivant :</p>
<ol>
<li>
<p>installer les binaires nécessaires : <br>
<code>$ doas pkg_add ldns-utils git</code> <br></p>
</li>
<li>
<p>télécharger et installer ldnscripts</p>
</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cd /usr/local/src/
</span></span><span style="display:flex;"><span>$ doas mkdir ldnscripts
</span></span><span style="display:flex;"><span>$ doas chown <span style="color:#ef6155">$USER</span> ldnscripts
</span></span><span style="display:flex;"><span>$ git clone https://framagit.org/22decembre/ldnscripts.git
</span></span><span style="display:flex;"><span>$ cd ldnscripts
</span></span><span style="display:flex;"><span>$ doas make install
</span></span></code></pre></div><ol start="3">
<li>configurer le fichier /etc/ns/ldnscript.conf</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">; SHA256 est largement suffisant et sécuritaire</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ALG</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">ECDSAP256SHA256 </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">NSEC3_ALG</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">SHA-256</span>
</span></span></code></pre></div><ol start="4">
<li>
<p>initialisation du domaine <br>
<code>$ doas ldnscript init domain.tld</code></p>
</li>
<li>
<p>nécessité de créer un lien symbolique /usr/bin/dig vers /usr/sbin/dig :<br>
<code>$ doas ln -sf /usr/bin/dig /usr/sbin/dig</code> <br>
<em>(sans ce dernier point, l&rsquo;outil <code>ldnscript</code> ne pourra trouver le binaire
<code>dig</code> et donc refusera de fonctionner en se mettant en erreur)</em>.</p>
</li>
</ol>
<h2 id="configuration">Configuration</h2>
<h3 id="etcmonthlylocal">/etc/monthly.local</h3>
<p>Tous les mois, je crée le rollover nécessaire des clés en intégrant dans
le script <code>/etc/monthly.local</code>, le code shell suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">### ldnscript</span>
</span></span><span style="display:flex;"><span>printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; ldnscript rollover&#34;</span>
</span></span><span style="display:flex;"><span>/usr/local/sbin/ldnscript rollover all
</span></span></code></pre></div><h4 id="lets-encrypt">Let&rsquo;s Encrypt</h4>
<p>Dans la foulée, du rollover des clés DNSSEC, mon script interroge les
services Let&rsquo;s Encrypt pour savoir s&rsquo;il faut un renouvellement des certificats
pour les noms de domaines que j&rsquo;utilise.</p>
<p>Normalement, on utiliserait le client <code>acme</code> natif sous OpenBSD, mais ayant
eu certains déboires, j&rsquo;ai décidé de basculer sur l&rsquo;usage de <code>certbot</code>.</p>
<p>Une simple écriture shell suffit pour le renouvellement : <br>
<code>/usr/local/bin/certbot renew --pre-hook &quot;rcctl stop nginx&quot; --post-hook &quot;rcctl start nginx&quot;</code></p>
<p><em>(en effet, j&rsquo;utilise aussi le serveur nginx, en lieu et place du serveur
web natif <strong>httpd</strong> - mais il suffit de remplacer le nom du service, si
jamais c&rsquo;est votre cas)</em>.</p>
<p>Bien-sûr, cette partie n&rsquo;entre pas directement en ligne de compte de la
gestion DNS. Néanmoins, c&rsquo;est important à prendre en compte car lors du
renouvellement de certificat, il est nécessaire de regénérer les enregistrements
TLSA - <em>nous verrons ce point plus tard</em>.</p>
<h3 id="exemple-zone-dns">Exemple zone DNS</h3>
<p>Voici pour l&rsquo;exemple une zone DNS minimaliste, gérée par le serveur <strong>ns</strong> :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">$TTL 1H
$ORIGIN domain.tld.
@   IN  SOA domain.tld. dns.domain.tld. (
    2022090101 ;
    3H ; refresh
    1H ; retry
    2W ; expire
    1H ; negative
)
                    
@   IN NS   ns1.domain.tld.
@   IN NS   ns2.domain.tld.

@   IN A    46.23.90.29
    IN AAAA 2a03:6000:6e65:619::29

; enregistrement CAA
@    IN CAA  0 iodef &#34;mailto:mail@domain.tld&#34;
@    IN CAA  0 issue &#34;letsencrypt.org&#34;
@    IN CAA  0 issuewild &#34;letsencrypt.org&#34;

www IN A    46.23.90.29
    IN AAAA 2a03:6000:6e65:619::29

; TLSA
_443._tcp.domain.tld. IN TLSA 3 1 2 5c8fdd68178ce4cd8d88bd90b82a96df41674d555340b88283c24a0b3416aa375144cd6c16a58160ba3b168e59f5003bff656ce67cb24931b462fe4910bd62f5
</code></pre><h2 id="shell">shell</h2>
<h3 id="générer-un-enregistrement-tlsa">Générer un Enregistrement TLSA</h3>
<p>En shell, générer un enregistrement TLSA n&rsquo;est pas compliqué :</p>
<p><code>openssl x509 -noout -pubkey -in &quot;${cert}&quot; | openssl &quot;${command}&quot; -pubin -outform der 2&gt;/dev/null | &quot;${algo}&quot; | tr &quot;a-z&quot; &quot;A-Z&quot;</code></p>
<p><strong>Explications</strong> :</p>
<p>⇒ La commande ci-dessus nous permet de générer une variable intermédiaire
nommée <code>tlsa_cert_associated</code> où :</p>
<ul>
<li>la variable <code>$cert</code> est le nom du chemin absolu du certificat TLS serveur,
dans le système de fichier du serveur, lié au domaine cible.</li>
<li>la variable <code>$command</code> est le nom de la commande utilisée par OpenSSL, soit
<code>rsa</code> ou <code>ec</code> <em>(réciproquement pour les enregistrements selon le chiffrement
RSA ou ECDSA)</em>.</li>
<li>et, où la variable <code>$algo</code> est le nom de l&rsquo;utilitaire <code>sha256</code>, ou <code>sha512</code>,
<em>au choix personnel et</em> restituera un condensé de message lié à
l&rsquo;algorithme choisi.</li>
</ul>
<p>⇒ l&rsquo;écriture relative à l&rsquo;enregistrement TLSA est aussi simple :</p>
<p><code>tlsa_record=&quot;_${tls_port}._${tls_proto}.${domain}. IN TLSA ${tlsa_usage} ${tlsa_selector} ${tlsa_method} ${tlsa_cert_associated}&quot;</code></p>
<p>où :</p>
<ul>
<li><code>${tls_port}</code> est le numéro de port du serveur web utilisé, ici <strong>443</strong></li>
<li><code>${tls_proto}</code> est le nom du protocole utilisé, ici <strong>tls</strong></li>
<li><code>${domain}</code> est le nom de domaine cible</li>
<li><code>${tlsa_usage}</code> est le chiffre correspondant à la contrainte utilisée,
ici <strong>3</strong>, correspondant à la contrainte <strong>DANE-EE</strong>, et recommandée
par Let&rsquo;s Encrypt.</li>
<li><code>${tlsa_selector}</code> est le chiffre correspondant au nom de sélecteur
utilisé, ici <strong>1</strong>, correspondant au sélecteur <strong>SPKI</strong>, là aussi
recommandé par Let&rsquo;s Encrypt.</li>
<li><code>${tlsa_method}</code> étant la méthode utilisant l&rsquo;algorithme de chiffrement
choisi ; ici <strong>SHA256</strong>, qui offre un niveau <em>actuel</em> de chiffrement
dit sécurisé et tout autant recommandé par Let&rsquo;s Encrypt.</li>
<li>et pour finir la variable <code>tlsa_cert_associated</code> précédemment créée.</li>
</ul>
<h3 id="vérifier-un-enregistrement-tlsa">Vérifier un Enregistrement TLSA</h3>
<p>Vérifier un enregistrement TLSA est un poil plus compliqué ; il faut :</p>
<ol>
<li>1/ interroger le serveur DNS pour connaître l&rsquo;enregistrement TLSA actuel
par le biais de l&rsquo;outil <code>dig</code>, pour l&rsquo;exemple.</li>
<li>2/ le comparer avec la sortie fournie par l&rsquo;outil <code>openssl</code> qui va interroger
le certificat installé sur le serveur web utilisé, lié au nom de domaine
en question.</li>
</ol>
<hr>
<ul>
<li>interroger le serveur DNS se fait ainsi :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dig TLSA _443._tcp.<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> +short<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">d_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk <span style="color:#48b685">&#39;{ for(i=4;i&lt;=NF;++i) printf &#34;%s&#34;, tolower($i); print &#34;&#34; }&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><ul>
<li>utiliser openssl pour interroger le certificat TLS utilisé sur le
serveur web :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo | openssl s_client -servername <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -showcerts -connect <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:443 2&gt;/dev/null | openssl x509 -noout -pubkey | openssl pkey -outform der -pubin 2&gt;/dev/null | openssl dgst -<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> 2&gt;/dev/null <span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">o_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk -F<span style="color:#48b685">&#39;=&#39;</span> <span style="color:#48b685">&#39;{ print $2 }&#39;</span> | tr -d <span style="color:#48b685">&#39; &#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><p>Pour finir, il suffit vraiment de comparer les deux variables shell
<code>d_tlsa</code> et <code>o_tlsa</code> pour savoir si elles correspondent, ce qui en temps
normal doit être le cas. <strong>Sauf en cas, de renouvellement de certificat
TLS, qui nécessitera donc de renouveller l&rsquo;enregistrement TLSA, dans la
zone du nom de domaine en question, sur le serveur DNS</strong>.</p>
<p>Pour rappel, si cela n&rsquo;est pas fait, une interrogation du serveur DNS sur
le protocole DNSSEC générera une erreur puisque l&rsquo;enregistrement TLSA ne
correspondra pas un certificat web fraîchement utilisé, ou renouvellé, ce
qui va entraîner cette conséquence : l&rsquo;accès au serveur, lié au nom de
domaine cible, sera impossible.</p>
<p>Il faudra donc générer un nouvel enregistrement TLSA correspondant au
renouvellement du certificat TLS, puis régénerer la signature des enregistrements
DNSSEC liés à la zone DNS du domaine cible.</p>
<h2 id="scripts-shell">Scripts Shell</h2>
<p>Pour info, les scripts shell <strong>tlsa.sh</strong>, <strong>dns.conf</strong>, <strong>dns.ksh</strong> sont
écrits dans un répertoire nommé <strong>dns-tools</strong> dans le répertoire personnel.
<em>À vous de voir où vous désirez les mettre, et modifier le script mensuel</em>.</p>
<h3 id="monthlylocal">monthly.local</h3>
<p>Voici la teneur de mon script shell <strong>monthly.local</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### ldnscript</span>
</span></span><span style="display:flex;"><span>printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; ldnscript rollover&#34;</span>
</span></span><span style="display:flex;"><span>/usr/local/sbin/ldnscript rollover all
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### renew ssl by certbot</span>
</span></span><span style="display:flex;"><span>printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; renew letsencrypt certs&#34;</span>
</span></span><span style="display:flex;"><span>/usr/local/bin/certbot renew --pre-hook <span style="color:#48b685">&#34;rcctl stop nginx&#34;</span> --post-hook <span style="color:#48b685">&#34;rcctl start nginx&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### check tlsa records for domain; only for tcp:443</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> domain in <span style="color:#48b685">&#34;sub.domain.tld&#34;</span> <span style="color:#48b685">&#34;domain.tld&#34;</span> <span style="color:#48b685">&#34;www.domain.tld&#34;</span> <span style="color:#48b685">&#34;sub.domain2.tld&#34;</span> <span style="color:#48b685">&#34;domain2.tld&#34;</span> <span style="color:#48b685">&#34;www.domain2.tld&#34;</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; Test TLSA for </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	/home/-your-user-/dns-tools/tlsa.sh <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="tlsash">tlsa.sh</h3>
<p>Voici mon script shell nommé <strong>tlsa.sh</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>set -e
</span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Author: Stéphane HUC</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mail: devs@stephane-huc.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># License: BSD Simplified</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Github: </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Date: 2022/07/01 06:45</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Purpose: tool  to test TLSA record</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  - for the geek: DANE-TLSA...</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Needed tools: dig, openssl</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># OS: Tested on OpenBSD, Devuan</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># see: https://www.bortzmeyer.org/monitor-dane.html</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>. <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/dns.conf&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_admin</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/home/-your-user-/dns-tools&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">domain</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### DO NOT TOUCH!</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">d_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;&#39;</span>	<span style="color:#776e71"># TLSA record by dig</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">o_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;&#39;</span>	<span style="color:#776e71"># TLSA record by openssl</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_record</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;&#39;</span>	<span style="color:#776e71"># TLSA record </span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">####</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   All needed functions! DO NOT TOUCH-IT!</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>byebye<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Script stop here!&#34;</span>
</span></span><span style="display:flex;"><span>    mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Please, search to understand reasons.&#34;</span>
</span></span><span style="display:flex;"><span>    exit <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_uid<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>id -u<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span> -ne <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: Script not launch with rights admin!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_dig<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dig TLSA _443._tcp.<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> +short<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">d_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo <span style="color:#ef6155">$tlsa</span> | awk <span style="color:#48b685">&#39;{ for(i=4;i&lt;=NF;++i) printf &#34;%s&#34;, tolower($i); print &#34;&#34; }&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_openssl<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo | openssl s_client -servername <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -showcerts -connect <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:443 2&gt;/dev/null | openssl x509 -noout -pubkey | openssl pkey -outform der -pubin 2&gt;/dev/null | openssl dgst -<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> 2&gt;/dev/null <span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">o_tlsa</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo <span style="color:#ef6155">$tlsa</span> | awk -F<span style="color:#48b685">&#39;=&#39;</span> <span style="color:#48b685">&#39;{ print $2 }&#39;</span> | tr -d <span style="color:#48b685">&#39; &#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mssg<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    typeset statut info text
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">statut</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> <span style="color:#ef6155">info</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$2</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;KO&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">text</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;[ </span><span style="color:#f99b15">${</span><span style="color:#ef6155">red</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">neutral</span><span style="color:#f99b15">}</span><span style="color:#48b685"> ]    </span><span style="color:#f99b15">${</span><span style="color:#ef6155">info</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> ;;
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;OK&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">text</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;[ </span><span style="color:#f99b15">${</span><span style="color:#ef6155">green</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">neutral</span><span style="color:#f99b15">}</span><span style="color:#48b685"> ]   </span><span style="color:#f99b15">${</span><span style="color:#ef6155">info</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> ;;
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#*) mssg=&#34;${text}&#34; ;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#34;%s \n&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">text</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset info statut text
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>new_tlsa<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">cert</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/etc/letsencrypt/live/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">/cert.pem&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">le_key_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in 
</span></span><span style="display:flex;"><span>		<span style="color:#48b685">&#34;ecdsa&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>openssl x509 -noout -pubkey -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl ec -pubin -outform der 2&gt;/dev/null | <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>		<span style="color:#48b685">&#34;rsa&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>openssl x509 -noout -pubkey -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl rsa -pubin -outform der 2&gt;/dev/null | <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">tlsa_record</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	unset tlsa_cert_associated
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">####</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   Execution</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;[ KO ] Script stops here; no domain!&#34;</span>; exit; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_dig
</span></span><span style="display:flex;"><span>_openssl
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">d_tlsa</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">o_tlsa</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>	mssg <span style="color:#48b685">&#34;OK&#34;</span> <span style="color:#48b685">&#34;Similar TLSA records! :D&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>	mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;There seems to be a problem with the TLSA records of the domain: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">!&#34;</span>
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;Have you renew recently the TLS certs for the domain? If yes, change the TLSA record into the DNS zone relevent!&#34;</span>
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n%s\n&#39;</span> <span style="color:#48b685">&#34;⇒ Perhaps, the dns.sh script shell can help you. ;-)&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	check_uid
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;⇒ Display new TLSA record:&#34;</span>
</span></span><span style="display:flex;"><span>	new_tlsa
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n%s\n&#39;</span> <span style="color:#48b685">&#34;Add/modify tlsa into your DNS zone for </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">: &#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;⇒ Modify TLSA record into the domain zone for </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_admin</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>/dns.ksh tlsa <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><p><strong>Modifiez la valeur de la variable <code>dir_admin</code> !</strong></p>
<p>Comme vous pouvez le remarquer :</p>
<ul>
<li>il fait appel au fichier de configuration <strong>dns.conf</strong>, <em>publié ci-dessous</em></li>
<li>et si la correspondance des enregistrements TLSA ne se fait pas, il
appelle le script pdksh <strong>dns.ksh</strong> avec l&rsquo;argument <code>tlsa</code> suivi du
nom de domaine à cibler</li>
</ul>
<h3 id="dnsconf">dns.conf</h3>
<p>Voici le fichier de configuration qui sert à la fois pour le script shell
<strong>tlsa.sh</strong> et le script pdksh <strong>dns.ksh</strong>.</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">########################################################################
#
# Author: Stéphane HUC
# mail: devs@stephane-huc.net
# gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58
#
# License: BSD Simplified
#
# Github: https://framagit.org/hucste/AH.git
#
# Date: 2022/06/01 07:20
#
########################################################################
###
##
# Config file to dns.ksh script
##
###
########################################################################

### Algorithm
## values: sha256, sha512; choose-it segun TLSA Method
algo=&#34;sha256&#34;
### SOA Serial type
## values: date, timestamp
## DNS recommandation: prefer date
SOA_serial_type=&#34;date&#34;
### Port number
tls_port=443
### Protocols
## values: stcp, tcp, udp
tls_proto=&#34;tcp&#34;

### TLSA 
## Lets Encrypt Recommandation; 
## 	see: https://community.letsencrypt.org/t/please-avoid-3-0-1-and-3-0-2-dane-tlsa-records-with-le-certificates/7022
## usage: Lets Encrypt recommands 3, at least 2
## values: 0 =&gt; 3; or (PKIX-TA, PKIX-EE, DANE-TA, DANE-EE; respectivly: 0 -&gt; 3)
tlsa_usage=3
## selector: Lets Encrypt recommands 1
## values: 0 or 1; or (CERT, SPKI; respectively: O or 1)
tlsa_selector=1
## method: Lets Encrypt recommands 1
## values: 0 =&gt; 2; or (FULL, SHA256, SHA512; respectively: 0 -&gt; 2)
# this change segun algo
tlsa_method=1

### Key Type Letsencrypt
## rsa or ecdsa
## if ecdsa, specify elliptic curve: secp256r1, secp384r1, secp512r1 (256 is enough)
le_key_type=ecdsa
le_curve=secp256r1
</code></pre><p>Personnellement, je fais le choix d&rsquo;utiliser :</p>
<ul>
<li>l&rsquo;algorithme <strong>sha512</strong>.</li>
<li>le type de clé <strong>ecdsa</strong> qui déclenche l&rsquo;utilisation de la commande <strong>ec</strong>
lors de l&rsquo;utilisation d&rsquo;openssl, par les scripts <strong>dns.ksh</strong> ou <strong>tlsa.sh</strong>.
Il est bien sûr possible d&rsquo;utiliser <strong>rsa</strong> ; dans ce cas, les scripts
shell n&rsquo;utiliseront pas la variable <code>le_curve</code>.</li>
</ul>
<h3 id="dnsksh">dns.ksh</h3>
<p>Ce script long et complexe est capable de :</p>
<ul>
<li>générer les signatures DNSSEC pour la zone DNS d&rsquo;un domaine cible.</li>
<li>modifier l&rsquo;enregistrement TLSA puis regénérer les signatures DNSSEC ;
dans ce cas :
<ul>
<li>récupèrer l&rsquo;enregistrement de numéro de série SOA en cours dans la
zone DNS du domaine cible</li>
<li>créer un nouveau fichier de zone DNS et sauvegarder l&rsquo;actuel</li>
<li>si le nouveau fichier de zone DNS est accessible, le script écrit :
<ul>
<li>un nouveau numéro de série SOA</li>
<li>remplace l&rsquo;ancien enregistrement TLSA par le nouveau</li>
<li>essaye de signer à nouveau la zone DNS à l&rsquo;aide du protocole DNSSEC
<ul>
<li>s&rsquo;il réussit, il supprime l&rsquo;ancien fichier de zone DNS</li>
<li>s&rsquo;il échoue, il avertit, arrête son exécution <strong>et</strong> dans ce cas,
il faudra renommer à la main la sauvegarde de la zone DNS
pour en faire à nouveau l&rsquo;actuelle, puis chercher à comprendre
pourquoi le script à échouer - dans ce cas-là, il est intéressant
de positionner la variable <code>debug</code> à <code>1</code>, ce qui activera la
journalisation des différentes étapes, et pourra aider à l&rsquo;analyse,
lors d&rsquo;une exécution manuelle.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Un petit coup de <code>./dns.ksh help</code> vous en dira peut-être plus sur son utilisation. ;)</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/ksh
</span></span></span><span style="display:flex;"><span>set -e
</span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Author: Stéphane HUC</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mail: devs@stephane-huc.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># License: BSD Simplified</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Github: </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Date: 2022/06/01 07:25</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Purpose: to add a TLSA Record into DNS zone, segun your cert TLS (LE)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  - for the geek: DANE-TLSA...</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#### IMPORTANT: recreate your TLSA Record after (re?)new cert...</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Needed tools: nsd* and ldnscript</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## ldnscript is a tool to sign dns zone. (DNSSEC)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## https://framagit.org/22decembre/ldnscripts.git</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># OS: Tested on OpenBSD</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>. <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/dns.conf&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   DONT TOUCH THOSES VARIABLES!</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">debug</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_le</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/etc/letsencrypt/live&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_ns_cfg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/etc/ns&#34;</span>    <span style="color:#776e71"># folder config ns</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_sbin</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/usr/local/sbin&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">log</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ROOT</span><span style="color:#f99b15">}</span><span style="color:#48b685">/dns-script.log&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">nsd_cfg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/var/nsd/etc/nsd.conf&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">timestamp</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>date +%s<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">today</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>date +<span style="color:#48b685">&#34;%Y%m%d&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">server</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nsd&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">SOA_ns</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_record</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>set -A tlsa_records	<span style="color:#776e71"># if X509 DNS Alternative Names &gt; 1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>set -A tlsa_method_names -- <span style="color:#48b685">&#34;FULL&#34;</span> <span style="color:#48b685">&#34;SHA256&#34;</span> <span style="color:#48b685">&#34;SHA512&#34;</span>
</span></span><span style="display:flex;"><span>set -A tlsa_selector_names -- <span style="color:#48b685">&#34;CERT&#34;</span> <span style="color:#48b685">&#34;SPKI&#34;</span>
</span></span><span style="display:flex;"><span>set -A tlsa_usage_names -- <span style="color:#48b685">&#34;PKIX-TA&#34;</span> <span style="color:#48b685">&#34;PKIX-EE&#34;</span> <span style="color:#48b685">&#34;DANE-TA&#34;</span> <span style="color:#48b685">&#34;DANE-EE&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">NB_PARAMS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$#</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>set -A PARAMS -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$@</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">PARAMS</span>[0]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> <span style="color:#ef6155">MENU_CHOICE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;help&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>    PARAMS<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>printf <span style="color:#48b685">&#39;%s&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">PARAMS</span>[0]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | tr -s <span style="color:#48b685">&#34;[:upper:]&#34;</span> <span style="color:#48b685">&#34;[:lower:]&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">MENU_CHOICE</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">PARAMS</span>[0]<span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> -n <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">PARAMS</span>[1]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#ef6155">domain</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>printf <span style="color:#48b685">&#39;%s&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">PARAMS</span>[1]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | tr -s <span style="color:#48b685">&#34;[:upper:]&#34;</span> <span style="color:#48b685">&#34;[:lower:]&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">####</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   All needed functions! DO NOT TOUCH-IT!</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_add_tlsa<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	check_var_algo
</span></span><span style="display:flex;"><span>	check_var_soa_serial_type
</span></span><span style="display:flex;"><span>	check_var_tls_port
</span></span><span style="display:flex;"><span>	check_var_tls_proto
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	check_tlsa_methods
</span></span><span style="display:flex;"><span>	check_tlsa_selectors
</span></span><span style="display:flex;"><span>	check_tlsa_usages
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	get_soa_ns
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">danefile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">.dane&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">newzonefile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">today</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">oldzonefile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>    create_new_filezone
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		write_soa_serial_number
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span>		build_tlsa_record
</span></span><span style="display:flex;"><span>		write_tlsa_record
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		mv_new_file_zone
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">if</span> _resign; <span style="color:#815ba4">then</span> del_old_zonefile; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	unset danefile newzonefile oldzonefile
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>build_needed_variables<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>    check_var_domain
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;*** Build needed variables:&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># build cert variable if menu &#39;tlsa&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MENU_CHOICE</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;tlsa&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">cert</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_le</span><span style="color:#f99b15">}</span><span style="color:#48b685">/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">/cert.pem&#34;</span>
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> ! -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;*** It seems cert file not exists!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>			printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;cert: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># build zonedir and zonefile variables</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">zonedir</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>awk -F <span style="color:#48b685">&#39;&#34;&#39;</span> <span style="color:#48b685">&#39;/zonesdir/ { print substr($2,-1) }&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">nsd_cfg</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonedir</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> <span style="color:#ef6155">zonedir</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/var/nsd/zones/&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;zonedir: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonedir</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#zonefile=&#34;$(awk -F &#39;&#34;&#39; &#39;/zonefile: &#34;[a-z]*\/&#39;&#34;${domain}&#34;&#39;&#34;/ { print substr($2, -1) }&#39; &#34;${nsd_cfg}&#34;)&#34;    </span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#if [ &#34;$(printf &#39;%s&#39; &#34;${zonefile}&#34; | awk -F&#39;/&#39; &#39;{ print $1}&#39;)&#34; == &#34;signed&#34; ]; then</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">##zonefilesigned=$zonefile        </span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#zonefile=&#34;$(find &#34;${dir_ns_cfg}&#34; -name &#34;${domain}&#34;)&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#if [ -z &#34;${zonefile}&#34; ]; then zonefile=&#34;$(find &#34;${zonedir}&#34; -name &#34;${domain}&#34;)&#34;; fi</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#if [ -z &#34;${zonefile}&#34; ]; then</span>
</span></span><span style="display:flex;"><span>            <span style="color:#776e71">#display_mssg &#34;KO&#34; &#34;ERROR: It seems zonefile for domain: &#39;${domain}&#39; not exists!&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#776e71">#byebye</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#else</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#zonefile=&#34;${zonedir}${zonefile}&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">zonefile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_ns_cfg</span><span style="color:#f99b15">}</span><span style="color:#48b685">/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;zonefile: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>build_tlsa_record<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># get TLSA by reading cert pem</span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">le_key_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in 
</span></span><span style="display:flex;"><span>		<span style="color:#48b685">&#34;ecdsa&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ef6155">command</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;ec&#34;</span>
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>		<span style="color:#48b685">&#34;rsa&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			<span style="color:#ef6155">command</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;rsa&#34;</span>
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>openssl x509 -noout -pubkey -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">command</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -pubin -outform der 2&gt;/dev/null | <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    _log <span style="color:#48b685">&#34;TLSA Cert Associated: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    unset command
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: TLSA Cert Associated could not generated!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># rebuild tlsa method segun algo choosed; possible: 0 (no match), 1 (sha256), 2 (sha512)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;sha256&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;sha512&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> ;;
</span></span><span style="display:flex;"><span>            *<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> ;;
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;443&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;tcp&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			get_dns_alternative_names
</span></span><span style="display:flex;"><span>			<span style="color:#ef6155">count</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${#</span><span style="color:#ef6155">domains</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>			
</span></span><span style="display:flex;"><span>			<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">count</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -eq <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>				set_tlsa_record			
</span></span><span style="display:flex;"><span>			<span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>				set_tlsa_records
</span></span><span style="display:flex;"><span>			<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>			
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset tlsa_cert_associated
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>byebye<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Script stop here!&#34;</span>
</span></span><span style="display:flex;"><span>    display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Please, search to understand reasons.&#34;</span>
</span></span><span style="display:flex;"><span>    exit <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_domain_name<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">pattern</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])</span>$<span style="color:#48b685">&#34;</span> <span style="color:#776e71"># like RFC 1123</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#f99b15">${#</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span> -gt <span style="color:#f99b15">67</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>    <span style="color:#776e71"># Larg domain name &lt;= 67</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Error: Domain Length: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">; &gt;= 67 carachters!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | grep -Eio <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">pattern</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;OK&#34;</span> <span style="color:#48b685">&#34;Domain Name: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685"> is valid!&#34;</span>
</span></span><span style="display:flex;"><span>        sleep <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Error: Bad Domain Name: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset pattern
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_tlsa_methods<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in 
</span></span><span style="display:flex;"><span>		0|<span style="color:#48b685">&#34;FULL&#34;</span><span style="color:#5bc4bf">)</span> 	<span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> ;; 
</span></span><span style="display:flex;"><span>		1|<span style="color:#48b685">&#34;SHA256&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>		2|<span style="color:#48b685">&#34;SHA512&#34;</span><span style="color:#5bc4bf">)</span>	<span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> ;;
</span></span><span style="display:flex;"><span>		*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\  The TLSA Method: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>		::
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLSA Method: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_tlsa_selectors<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in 
</span></span><span style="display:flex;"><span>		0|<span style="color:#48b685">&#34;CERT&#34;</span><span style="color:#5bc4bf">)</span> 	<span style="color:#ef6155">tlsa_selector</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> ;; 
</span></span><span style="display:flex;"><span>		1|<span style="color:#48b685">&#34;SPKI&#34;</span><span style="color:#5bc4bf">)</span> 	<span style="color:#ef6155">tlsa_selector</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>		*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\  The TLSA Selector: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLSA Selector: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_tlsa_usages<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in 
</span></span><span style="display:flex;"><span>		0|<span style="color:#48b685">&#34;PKIX-TA&#34;</span><span style="color:#5bc4bf">)</span> 	<span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> ;; 
</span></span><span style="display:flex;"><span>		1|<span style="color:#48b685">&#34;PKIX-EE&#34;</span><span style="color:#5bc4bf">)</span> 	<span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>		2|<span style="color:#48b685">&#34;DANE-TA&#34;</span><span style="color:#5bc4bf">)</span>	<span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> ;;
</span></span><span style="display:flex;"><span>		3|<span style="color:#48b685">&#34;DANE-EE&#34;</span><span style="color:#5bc4bf">)</span>	<span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span> ;;
</span></span><span style="display:flex;"><span>		*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\  The TLSA Usage: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>		;;
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLSA Usage: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_uid<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>id -u<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span> -ne <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: Script not launch with rights admin!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_var_algo <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;sha256&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;sha512&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\ Algorythm: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;Algo: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_var_domain<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;*** It seems fault informations!&#34;</span>
</span></span><span style="display:flex;"><span>        help
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    _log <span style="color:#48b685">&#34;Domain: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_var_soa_serial_type<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_serial_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;date&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_serial_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;timestamp&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\ SOA Serial Type: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;SOA Serial Type: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_serial_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_var_tls_port<span style="color:#5bc4bf">(){</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -lt <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>		display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\ TLS port: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>		byebye
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span> 
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLS port: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>check_var_tls_proto<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;sctp&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;tcp&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;tcp&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\ TLS proto: not correctly configurated!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLS proto: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>checkconf<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    nsd-checkconf <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">nsd_cfg</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>checkzone<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    nsd-checkzone <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>confirm <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    read -r response?<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">1</span><span style="color:#f99b15">}</span><span style="color:#48b685"> [y|n] &#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">response</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># &#39;o&#39;, &#39;O&#39;: Oui and not 0!</span>
</span></span><span style="display:flex;"><span>        y|Y|o|O|1<span style="color:#5bc4bf">)</span>  true ;;
</span></span><span style="display:flex;"><span>        *<span style="color:#5bc4bf">)</span>          false ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>    unset response
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>create_new_filezone<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	cp <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>del_old_zonefile<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">oldzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        rm -fP <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">oldzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>display_mssg<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    typeset statut info text
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">statut</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> <span style="color:#ef6155">info</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$2</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;KO&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">text</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;[ </span><span style="color:#f99b15">${</span><span style="color:#ef6155">red</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">neutral</span><span style="color:#f99b15">}</span><span style="color:#48b685"> ]    </span><span style="color:#f99b15">${</span><span style="color:#ef6155">info</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> ;;
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;OK&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">text</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;[ </span><span style="color:#f99b15">${</span><span style="color:#ef6155">green</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">statut</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">neutral</span><span style="color:#f99b15">}</span><span style="color:#48b685"> ]   </span><span style="color:#f99b15">${</span><span style="color:#ef6155">info</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> ;;
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#*) mssg=&#34;${text}&#34; ;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#34;%s \n&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">text</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset info statut text
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>get_dns_alternative_names<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># get &#34;X509 DNS Alternative Names&#34; characters</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">domains</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>echo | openssl x509 -text -noout -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk -F <span style="color:#48b685">&#39;,&#39;</span> <span style="color:#48b685">&#39;/DNS:/ { for(i=1;i&lt;NF;i++) { p=match($i,&#34;:&#34;); print substr($i,p+1) }}&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># convert into array; no double-quotes, else not run!</span>
</span></span><span style="display:flex;"><span>	set -A domains -- <span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[@]<span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span>	printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;domains: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[*]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;domains: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[*]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>get_soa_ns<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>grep -A1 <span style="color:#48b685">&#34;SOA&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | tail -n1 | awk -F <span style="color:#48b685">&#39; &#39;</span> <span style="color:#48b685">&#39;{ print $1 }&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;Old SOA Serial Number: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">!&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>get_soa_serial_number<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">line</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk -F <span style="color:#48b685">&#39; &#39;</span> <span style="color:#48b685">&#39;{ print $1 }&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;OLD SOA Serial Number: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>help<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    </span><span style="color:#ef6155">$0</span><span style="color:#48b685"> sign domain      # to sign a domain
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    </span><span style="color:#ef6155">$0</span><span style="color:#48b685"> tlsa domain      # to add a tlsa record into domain zone
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ----
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    when use tlsa, this script will resign the domain zone...
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>init_zone<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_sbin</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>/ldnscript init <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>in_array<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    local <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#ef6155">need</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> <span style="color:#ef6155">IFS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34; &#34;</span>; shift; set -A array -- <span style="color:#ef6155">$*</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">count</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${#</span><span style="color:#ef6155">array</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">while</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$i</span> -le <span style="color:#ef6155">$count</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">array</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">need</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> <span style="color:#815ba4">return</span> 0; <span style="color:#815ba4">fi</span> <span style="color:#776e71"># true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">#let &#34;i=$i+1&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span>i+1 <span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    unset i need IFS array
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_log<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">debug</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -eq <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> &gt;&gt; <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">log</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>main<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span>	check_uid
</span></span><span style="display:flex;"><span>	verify_need_softs
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	build_needed_variables
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>    check_domain_name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MENU_CHOICE</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;help&#34;</span><span style="color:#5bc4bf">)</span> help ;;
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;sign&#34;</span><span style="color:#5bc4bf">)</span> _resign ;;
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;tlsa&#34;</span><span style="color:#5bc4bf">)</span> _add_tlsa ;;
</span></span><span style="display:flex;"><span>        *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: this option </span><span style="color:#f99b15">${</span><span style="color:#ef6155">MENU_CHOICE</span><span style="color:#f99b15">}</span><span style="color:#48b685"> is not exists!&#34;</span>
</span></span><span style="display:flex;"><span>            help
</span></span><span style="display:flex;"><span>            byebye
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mv_new_file_zone<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        mv <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">oldzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        mv <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">zonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_resign<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> checkzone <span style="color:#5bc4bf">&amp;&amp;</span> checkconf; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;OK&#34;</span> <span style="color:#48b685">&#34;file config nsd and zone </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685"> are good! :D&#34;</span>
</span></span><span style="display:flex;"><span>        sign_zone
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: it exists a problem with file config nsd or zone </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>restart_server<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; Restart Server: &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    stop_server
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    start_server
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    status_server
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>set_soa_serial_number<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_serial_type</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;date&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            <span style="color:#ef6155">SOA_date</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>printf <span style="color:#48b685">&#39;%s&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk <span style="color:#48b685">&#39;{print substr($0, 0, 8)}&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>            <span style="color:#ef6155">SOA_number</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>printf <span style="color:#48b685">&#39;%s&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | awk <span style="color:#48b685">&#39;{print substr($0, 9)}&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_date</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">==</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">today</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>                <span style="color:#776e71">#let SOA_number=$SOA_number+1</span>
</span></span><span style="display:flex;"><span>                <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">SOA_number</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_number</span><span style="color:#f99b15">}</span>+1 <span style="color:#5bc4bf">))</span> <span style="color:#5bc4bf">||</span> true
</span></span><span style="display:flex;"><span>                <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_number</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -lt <span style="color:#f99b15">10</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> <span style="color:#ef6155">SOA_number</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;0</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_number</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ef6155">SOA_sn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_date</span><span style="color:#f99b15">}${</span><span style="color:#ef6155">SOA_number</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ef6155">SOA_sn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">today</span><span style="color:#f99b15">}</span><span style="color:#48b685">01&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#34;timestamp&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            <span style="color:#ef6155">SOA_sn</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">timestamp</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>        *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>			display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Invalid SOA Serial Type!&#34;</span>
</span></span><span style="display:flex;"><span>			byebye
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>    _log <span style="color:#48b685">&#34;New SOA Serial Number: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685">!&#34;</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>set_tlsa_record<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># build tlsa record</span>
</span></span><span style="display:flex;"><span>	tlsa_records<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[0]<span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLSA Record: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_records</span>[0]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>set_tlsa_records<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># do not use domain variable here</span>
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">for</span> dom in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">do</span> 
</span></span><span style="display:flex;"><span>		tlsa_records<span style="color:#5bc4bf">[</span><span style="color:#ef6155">$i</span><span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dom</span><span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#5bc4bf">((</span> <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span>i+1 <span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>	unset i dom
</span></span><span style="display:flex;"><span>	_log <span style="color:#48b685">&#34;TLSA Records: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_records</span>[*]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sign_zone<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_sbin</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>/ldnscript signing <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>start_server<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;Start serveur: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    rcctl start <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    sleep 1s
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>status_server<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;Check serveur: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    rcctl check <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>stop_server<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;Stop serveur: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    rcctl stop <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">server</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    sleep 1s
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>verify_need_softs<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> ! -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_sbin</span><span style="color:#f99b15">}</span><span style="color:#48b685">/ldnscript&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: ldnscript seems not install!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">elif</span> <span style="color:#5bc4bf">[</span> ! -x <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_sbin</span><span style="color:#f99b15">}</span><span style="color:#48b685">/ldnscript&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;ERROR: ldnscript is not executable!&#34;</span>
</span></span><span style="display:flex;"><span>        byebye
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>write_soa_serial_number<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	set_soa_serial_number
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> sed -i -e <span style="color:#48b685">&#34;s#\(.*\)</span><span style="color:#f99b15">${</span><span style="color:#ef6155">OLD_SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685"> \;#\1</span><span style="color:#f99b15">${</span><span style="color:#ef6155">SOA_sn</span><span style="color:#f99b15">}</span><span style="color:#48b685"> \;#&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>		_log <span style="color:#48b685">&#34;SOA serial number changed!&#34;</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">else</span> 
</span></span><span style="display:flex;"><span>		display_mssg <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;/!\  Script cant change SOA serial number!&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>write_tlsa_record<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> ! -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">danefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span> touch <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">danefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># add tlsa records into dns zone</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> tlsa_record in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_records</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>		<span style="color:#ef6155">dom</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		_log <span style="color:#48b685">&#34;domain: </span><span style="color:#ef6155">$dom</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#776e71">### /!\ ERROR with $domain /!\ </span>
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">if</span> sed -i -e <span style="color:#48b685">&#34;s#_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dom</span><span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA\(.*\)#</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">#&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>			_log <span style="color:#48b685">&#34;TLSA Record rewrited!&#34;</span>
</span></span><span style="display:flex;"><span>						
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>			printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> &gt;&gt; <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">newzonefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>			_log <span style="color:#48b685">&#34;TLSA Record added!&#34;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span>		<span style="color:#5bc4bf">((</span> <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span>i+1 <span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>		<span style="color:#776e71"># add record in first line into dane file</span>
</span></span><span style="display:flex;"><span>		printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">timestamp</span><span style="color:#f99b15">}</span><span style="color:#48b685">:</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> &gt;&gt; <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">danefile</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		_log <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">timestamp</span><span style="color:#f99b15">}</span><span style="color:#48b685">:</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>		unset dom
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>    unset i tlsa_record
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>main
</span></span></code></pre></div><hr>
<h2 id="eod">EOD</h2>
<p><strong>End Of Documentation</strong></p>
<p>Voilà mon processus de gestion de mes zones DNS, avec le protocole DNSSEC
et les enregistrements TLSA pour le service web.</p>
<p>D&rsquo;un processus long et complexe, je peux ainsi gérer simplement à l&rsquo;aide
de deux commandes bien utiles :</p>
<ul>
<li>signer par DNNSEC mes zones DNS :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./dns.ksh sign domain
</span></span></code></pre></div><ul>
<li>tester les enregistrements TLSA à tout moment, et si besoin les regénérer :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./tlsa.sh domain
</span></span></code></pre></div><p>Mais si vous avez bien compris, c&rsquo;est le cron mensuel qui s&rsquo;en occupe tout
seul et qui me fait le rapport adéquat, ainsi je sais comment cela s&rsquo;est
exécuté.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment gérer DNSSEC, les enregistrements TLSA, pour valider les certificats TLS sous OpenBSD avec nsd, ldns et consorts…]]></summary>
        <published>2022-09-01T00:32:16+02:00</published>
        <updated>2022-09-01T14:23:14+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e5e45f37-9a98-c2a6-0b56-5c6b1df3b937</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/mfp-scanner-epson/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MFP Scanner Epson sous Debian/Devuan</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <category term="MFP" scheme="http://doc.huc.fr.eu.org/fr/tags/mfp/" />
        <category term="scanner" scheme="http://doc.huc.fr.eu.org/fr/tags/scanner/" />
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Devuan" scheme="http://doc.huc.fr.eu.org/fr/tags/devuan/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Cet article devrait vous permettre d&rsquo;utiliser la partie des scanners,
pour votre imprimante multi-fonctions, appelée <abbr title="Multi Function Printer">MFP</abbr>
.</p>
<p>Le logiciel suivant est disponible depuis le site web officiel de
téléchargement d&rsquo;Epson <br>
<a href="http://download.ebz.epson.net/dsc/search/01/search/?OSC=LX" rel="external">http://download.ebz.epson.net/dsc/search/01/search/?OSC=LX</a> :</p>
<ul>
<li><a href="/fr/sys/debian/mfp-scanner-epson/#epson-scan-v2">Epson Scan</a></li>
</ul>
<p>Une fois installé, vous le retrouverez à-partir du menu &ldquo;Applications&rdquo; &gt;
&ldquo;Graphisme&rdquo;.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pour info, le logiciel <strong>XSane</strong> devrait fonctionner avec votre MFP, à partir
du moment où le fichier de configuration est correctement rempli ! <br>
Celui-ci est disponible depuis les dépôts officiels de la distribution…</div>

<p>Deux pilotes seront utilisés, selon votre imprimante MFP :</p>
<ul>
<li><a href="/fr/sys/debian/mfp-scanner-epson/#pilote-epkowa">Epkowa</a></li>
<li><a href="/fr/sys/debian/mfp-scanner-epson/#pilote-utsushi">Utsushi</a></li>
</ul>
<h3 id="pilote-epkowa">Pilote Epkowa</h3>
<p>Ce pilote concerne principalement les imprimantes MFP suivantes :</p>
<ul>
<li>Stylus, Stylus Photo, Stylus Office</li>
<li>certaines Workforce,</li>
<li>diverses XP,</li>
<li>et bien d&rsquo;autres…</li>
</ul>
<p><em><a href="http://download.ebz.epson.net/dsc/du/02/DriverDownloadInfo.do?LG2=EN&amp;CN2=&amp;DSCMI=97917&amp;DSCCHK=21fecde1d2b0b001f990e149dd9a9d5a8b5b04ea" rel="external">Plus d&rsquo;infos</a>…</em></p>
<h3 id="pilote-utsushi">Pilote Utsushi</h3>
<p>Le pilote <strong>Utsushi</strong> est un nouveau pilote en cours d&rsquo;écriture.</p>
<p>Le dépôt officiel : <a href="https://gitlab.com/utsushi/utsushi" rel="external">https://gitlab.com/utsushi/utsushi</a></p>
<p>Il est prévu à certain terme l&rsquo;intégration dans le projet Sane, mais il est
actuellement considéré en tant que &ldquo;External Backend&rdquo;. <br>
<a href="http://www.sane-project.org/lists/sane-backends-external.html#S-UTSUSHI" rel="external">http://www.sane-project.org/lists/sane-backends-external.html#S-UTSUSHI</a></p>
<p>Ce pilote concerne principalement les imprimantes MFP suivantes :</p>
<ul>
<li>certaines séries DS, EC, EP, ES</li>
<li>la série des EcoTank ET</li>
<li>beaucoup des séries WF, et XP</li>
<li>et bien d&rsquo;autres encore…</li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Ne pas hésitez à chercher avec une version supérieure, ainsi :</p>
<ul>
<li>la série ET-27xx semble être gérée par le pilote pour l&rsquo;ET-2750</li>
<li>idem pour les série ET-37xx, ET-47xx. <br>
<em>La capture ci-dessus montre un test depuis l&rsquo;EcoTank ET-3700 !</em></li>
</ul>
<p>Mettre un tiret entre les deux, tel que <strong>ET-3700</strong>. Faire une recherche
avec un espace échouera !</p>
<p>Etc.</p>
</div>

<h2 id="installation">Installation</h2>
<p>Maintenant, passons à l&rsquo;installation :</p>
<ul>
<li>d&rsquo;**<a href="/fr/sys/debian/mfp-scanner-epson/#epson-scan-v2">Epson Scan</a></li>
</ul>
<h3 id="epson-scan-v2">Epson Scan v2</h3>
<div class="float-right">
![Epson Scan2 v6.6.2](/images/debian/Epson-Scan2-v6.6.2.x.png?w=250 "Écran du logiciel 'Epson Scan 2 v6.6.2.x'")
</div>
<p>Actuellement à la version <strong>6.7.80</strong>, ce logiciel est très simple d&rsquo;utilisation.</p>
<p>La version 6 est disponible à partir de cette URL : <br>
<a href="http://support.epson.net/linux/en/epsonscan2.php" rel="external">http://support.epson.net/linux/en/epsonscan2.php</a></p>
<p>Une fois téléchargée, décompressez-la ; dirigez-vous dans le répertoire nommé
&ldquo;epsonscan2-bundle-6.7.80.0.x86_64.deb&rdquo; puis exécutez le script <code>install.sh</code>,
avec les droits administrateurs.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ epsonscan2-bundle-6.7.80.0.x86_64.deb
</span></span><span style="display:flex;"><span>:# ./install.sh
</span></span></code></pre></div><hr>
<p>Lors de la première fois, une première fenêtre &ldquo;Ajouter un scanner réseau&rdquo;
s&rsquo;ouvre et demande de restituer l&rsquo;adresse IP de votre MFP.</p>
<p>
    
                <figure role="figure" aria-label="Epscon Scan2 v6.6.2">
    <a href="/images/debian/Epson-Scan2-v6.6.2.x-add-scanner.png" title="Epscon Scan2 v6.6.2">
        <picture>
            <source srcset="/images/debian/Epson-Scan2-v6.6.2.x-add-scanner.png.avif" type="image/avif"><source srcset="/images/debian/Epson-Scan2-v6.6.2.x-add-scanner_hu_d3f62fde2fcad54d.webp" type="image/webp">
            <img alt="Epscon Scan2 v6.6.2" height="159" id="img_images_debian_Epson-Scan2-v6.6.2.x-add-scanner.png_0" loading="lazy" src="/images/debian/Epson-Scan2-v6.6.2.x-add-scanner.png" type="image/png" width="250">
        </picture>
    </a>
    <figcaption>Epscon Scan2 v6.6.2</figcaption>
</figure></p>
<p>Puis cliquez sur le bouton [ Ajouter ] qui se sera activé, suivi d&rsquo;un clic
sur le bouton [ OK ].</p>
<p>Il n&rsquo;y a plus qu&rsquo;à l&rsquo;utiliser, voire à modifier quelques paramètrages, à
vos besoins. Les boutons [ Aperçu ] et [ Numériser ] sont en bas.</p>
<h2 id="documentation">Documentation</h2>
<p>Epson fournit de la documentation, en anglais, pour aider à configurer le
logiciel <strong>Epson Scan</strong> :</p>
<ul>
<li>format <a href="https://download.ebz.epson.net/man/linux/epsonscan2_e.html" rel="external">html</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Tutoriel pour faire fonctionner le scanner des imprimantes multifonctions de la marque Epson]]></summary>
        <published>2022-05-03T08:52:24+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:324120b1-fad5-e2d6-5b70-1f47752b7938</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vger-voyager-gemini/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: V&#39;Ger Voyager / Gemini (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Gemini" scheme="http://doc.huc.fr.eu.org/fr/tags/gemini/" />
        <category term="VGer" scheme="http://doc.huc.fr.eu.org/fr/tags/vger/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="relayd" scheme="http://doc.huc.fr.eu.org/fr/tags/relayd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>V&rsquo;Ger</strong> est le projet de serveur de publication sur le protocol Gemini,
écrit en C. Écrit pour OpenBSD, il bénéficie des mesures de protections,
liées à pledge(4) et unveil(4).</p>
<p>Dans cet article, nous aborderons l&rsquo;installation et la configuration de
ce service. Puis nous verrons comment configurer <strong>relayd</strong> ou <strong>nginx</strong>
en tant que proxy relais ; et nous finirons par quelques règles pour
Packet-Filter.</p>
<p>OpenBSD : <del>6.9</del> → 7.4</p>
<hr>
<ul>
<li>Auteure du projet <strong>V&rsquo;Ger</strong> : Solène Rapenne</li>
<li>Disponible en tant que paquet : <a href="https://openports.pl/path/net/vger" rel="external">https://openports.pl/path/net/vger</a></li>
<li>URL du dépôt Git : <a href="https://tildegit.org/solene/vger" rel="external">https://tildegit.org/solene/vger</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Puisque V&rsquo;Ger est disponible dans les ports,
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le paquet <strong>vger</strong>.</p>
<hr>
<p><em>Autrement vous pouvez toujours l&rsquo;installer depuis le dépôt Git… mais là,
je vous renvoie à la documention du dépôt</em>.</p>
<h2 id="configuration">Configuration</h2>
<p>Pré-requis :</p>
<ul>
<li>changez les termes &lsquo;addresse_ipv4&rsquo;, &lsquo;addresse_ipv6&rsquo; et &rsquo;nom_domaine&rsquo;,
par ce qui correspond à votre contexte de serveur !</li>
</ul>
<h3 id="utilisateur-dédié-_vger">Utilisateur dédié _vger</h3>
<p>Créons en tout premier un utilisateur dédié, nommé <strong>_vger</strong> :</p>
<p><code>$ doas useradd -d /var/gemini -s /sbin/nologin _vger</code></p>
<p><em>(dans la documentation officielle, le nom de l&rsquo;utilisateur est <strong>_gemini</strong>)</em>.</p>
<h3 id="système">Système</h3>
<p>Il nous faut créer le répertoire <code>/var/gemini</code> puis appliquer les droits
à l&rsquo;utilisateur dédié :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas mkdir -p /var/gemini/nom_domaine
</span></span><span style="display:flex;"><span>$ doas chown -R _vger /var/gemini
</span></span></code></pre></div><h3 id="inetd">inetd</h3>
<ul>
<li>Fichier de configuraton : <code>/etc/inetd.conf</code></li>
</ul>
<p>Le service inetd est chargé de l&rsquo;écoute active sur l&rsquo;interface localhost
puis appelle le binaire vger pour délivrer le contenu.</p>
<p>Configurons maintenant le service <strong>inetd</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">1965 stream tcp nowait _vger /usr/local/bin/vger vger -d /var/gemini -v </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">1965 stream tcp6 nowait _vger /usr/local/bin/vger vger -d /var/gemini -v</span>
</span></span></code></pre></div><ul>
<li>le port d&rsquo;écoute est le <strong>1965</strong> - <em>(dans la documentation officielle,
le port par défaut est <strong>11965</strong>)</em>.</li>
<li>géré par l&rsquo;utilisateur <strong>_vger</strong>, appelant le binaire <code>vger</code>.</li>
</ul>
<p>⇒ activons et démarrons le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas rcctl enable inetd <span style="color:#5bc4bf">&amp;&amp;</span> doas rcctl start inetd
</span></span></code></pre></div><h3 id="certificats-ssl">certificats SSL</h3>
<p>Cet article ne présente pas comment obtenir les certificats SSL, mais vous
pouvez les obtenir, soit depuis le client acme secure, natif sous OpenBSD,
soit à partir du paquet certbot.</p>
<p>En premier, il semble <strong>nécessaire de créer le répertoire <code>private</code> dans <code>/etc/ssl</code></strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas mkdir -p /etc/ssl/private
</span></span></code></pre></div><h4 id="acme">acme</h4>
<p>La documentation officielle informe de lier les certificats SSL, générés
par le client sécurisé acme sous OpenBSD.</p>
<p>Si c&rsquo;est votre cas :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas ln -s /etc/ssl/acme/cert.pem /etc/ssl/nom_domaine.crt
</span></span><span style="display:flex;"><span>$ doas ln -s /etc/ssl/acme/private/privkey.pem /etc/ssl/private/nom_domaine.key
</span></span></code></pre></div><h4 id="certbot">certbot</h4>
<p>Dans mon contexte de serveur, les certificats sont générés par le client
certbot, disponible officiellement dans les ports. Une fois les certificats
générés par certbot, les liens symboliques à créer sont de cette forme :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas ln -s /etc/letsencrypt/live/nom_domaine/cert.pem /etc/ssl/nom_domaine.crt
</span></span><span style="display:flex;"><span>$ doas ln -s /etc/letsencrypt/live/nom_domaine/privkey.pem /etc/ssl/private/nom_domaine.key
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<ul>
<li>Fichier de configuration : <code>/etc/relayd.conf</code> - chmod <strong>0600</strong> !</li>
</ul>
<p><strong>relayd</strong> est le service de relais-proxy natif sous OpenBSD.</p>
<p>La configuration du service relayd peut se faire ainsi - <em>dans cet exemple,
à la fois pour Ipv4|6</em> - :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">log connection</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;localhost&gt; { 127.0.0.1, ::1 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">tcp protocol &#34;gemini&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls keypair nom_domaine</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">relay &#34;gemini&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on nom_domaine port 1965 tls</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">protocol &#34;gemini&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward to &lt;localhost&gt; port 1965</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>⇒ Vérification de la configuration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas relayd -n              
</span></span><span style="display:flex;"><span>host_dns: nom_domaine resolves to more than <span style="color:#f99b15">1</span> hosts
</span></span><span style="display:flex;"><span>configuration OK
</span></span></code></pre></div><p>⇒ activons et démarrons le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas rcctl enable relayd <span style="color:#5bc4bf">&amp;&amp;</span> doas rcctl start relayd
</span></span></code></pre></div><h3 id="nginx">nginx</h3>
<ul>
<li>Fichier de configuration : <code>/etc/nginx.conf</code></li>
</ul>
<p><strong>nginx</strong> peut lui aussi servir de proxy relais, en lieu et place de <strong>relayd</strong> ;
mais il est nécessaire d&rsquo;installer en plus le paquet <strong>nginx-stream</strong>.</p>
<p>Puis il faut modifier la configuration pour y ajouter, en début de fichier,
avant la directive <code>http</code> :<br>
<code>load_module &quot;modules/ngx_stream_module.so&quot;;</code></p>
<p>Ensuite, il est nécessaire de rajouter les déclarations suivantes en utilisant
la directive <code>stream</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">stream {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">log_format basic &#39;$remote_addr $upstream_addr [$time_local] &#39;</span>
</span></span><span style="display:flex;"><span>                     <span style="color:#06b6ef">&#39;$protocol $status $bytes_sent $bytes_received &#39;</span>
</span></span><span style="display:flex;"><span>                     <span style="color:#06b6ef">&#39;$session_time&#39;;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">access_log logs/nom_domaine/access.gemini.log basic;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">upstream backend_ipv4 {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">hash $remote_addr consistent;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">server 127.0.0.1:1965;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">upstream backend_ipv6 {</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">hash $remote_addr consistent;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">server [::1]:1965;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">map $server_addr $backend {</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">addresse_ipv4 backend_ipv4;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">addresse_ipv6 backend_ipv6;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">server {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">listen addresse_ipv4:1965 ssl;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">listen [addresse_ipv6]:1965 ssl;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">ssl_certificate /etc/letsencrypt/live/nom_domaine/fullchain.pem;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">ssl_certificate_key /etc/letsencrypt/live/nom_domaine/privkey.pem;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">ssl_ciphers TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">ssl_ecdh_curve X25519:P-521:P-384:P-256;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">ssl_prefer_server_ciphers on;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#06b6ef">ssl_protocols TLSv1.3 TLSv1.2;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">proxy_pass $backend;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Quelques petites explications :</p>
<ul>
<li>
<p>en rapport avec les directives <code>listen</code>, si vous ne déclarez pas l&rsquo;adresse
IP correspondante, tel que <code>listen 1965 ssl;</code>, il faudra impérativement
rediriger le port sur un autre numéro de port puis reconfigurer <code>inetd.conf</code>
pour qu&rsquo;il écoute sur ce même autre numéro de port. En effet, si l&rsquo;adresse
IP d&rsquo;écoute n&rsquo;est pas spécifiée dans la directive <code>listen</code>, nginx cherchera
à écouter sur toutes les interfaces réseaux configurées et ne pourra redémarrer
car inetd écoute déjà sur l&rsquo;interface localhost.</p>
</li>
<li>
<p>deux directives <code>upstream</code> sont déclarées, chacune pour gérer correctement
le protocole IPv4 ou IPv6, et sont mappées pour n&rsquo;avoir qu&rsquo;un seul proxy
à appeler.</p>
</li>
<li>
<p>un dernier mot, concernant les directives <code>ssl_ciphers</code>, <code>ssl_ecdh_curve</code>,
<code>ssl_prefer_server_ciphers</code>, et <code>ssl_protocols</code>, elles ne sont pas strictement
nécessaires mais utiles pour renforcer les préférences d&rsquo;utilisation.
<code>ssl_protocols</code> permet de prioriser la version de TLS, sachant que :<br></p>
</li>
</ul>
<blockquote>
<p>Servers MUST use TLS version 1.2 or higher and SHOULD use TLS version 1.3 or higher.</p>
</blockquote>
<h3 id="pf">PF</h3>
<p>Voici un exemple de règles minimalistes à ajouter à PF :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">host</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">adresse_ipv4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">host6</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">adresse_ipv6</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto tcp from any to { $host $host6 } port 1965</span>
</span></span></code></pre></div><p>Pensez à recharger le jeu de règles par PF :<br>
<code>$ doas pfctl -f /etc/pf.conf</code></p>
<hr>
<p>Voilà !</p>
<p>Il ne vous reste plus qu&rsquo;à créer votre premier fichier <code>index.gmi</code> et les
suivants et les déposer dans le répertoire correspondant à votre répertoire
de publication… en n&rsquo;oubliant pas de poser les droits de l&rsquo;utilisateur
dédié dessus.</p>
<h2 id="surveillance">Surveillance</h2>
<blockquote>
<p>Mais qui surveille ?</p>
</blockquote>
<p>⇒ L&rsquo;activité est enregistrée dans les deux logs &lsquo;daemon&rsquo; et &lsquo;messages&rsquo;.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ grep vger /var/log/messages                                                                                                              
</span></span><span style="display:flex;"><span>May  <span style="color:#f99b15">1</span> 10:54:28 sh1 useradd<span style="color:#5bc4bf">[</span>86659<span style="color:#5bc4bf">]</span>: new group added: <span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>_vger, <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1011</span>
</span></span><span style="display:flex;"><span>May  <span style="color:#f99b15">1</span> 10:54:28 sh1 useradd<span style="color:#5bc4bf">[</span>86659<span style="color:#5bc4bf">]</span>: new user added: <span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>_vger, <span style="color:#ef6155">uid</span><span style="color:#5bc4bf">=</span>1011, <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span>1011, <span style="color:#ef6155">home</span><span style="color:#5bc4bf">=</span>/var/gemini, <span style="color:#ef6155">shell</span><span style="color:#5bc4bf">=</span>/sbin/nologin
</span></span><span style="display:flex;"><span>May  <span style="color:#f99b15">1</span> 12:09:53 sh1 vger: request gemini://huc.fr.eu.org/
</span></span><span style="display:flex;"><span>May  <span style="color:#f99b15">1</span> 13:00:59 sh1 vger: request gemini://huc.fr.eu.org/
</span></span></code></pre></div><p>⇒ Il est possible de surveiller l&rsquo;activité de l&rsquo;utilisateur <strong>_vger</strong>
avec - <em>mais dans ce cas, franchement peu utile</em> :</p>
<ul>
<li><code>top -U _vger</code></li>
<li><code>fstat -u _vger -n</code></li>
<li><code>ps aux -U _vger</code></li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<p>⇒ Pour vérifier que le service inetd écoute en local, il est possible de
lui envoyer la requête suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ printf <span style="color:#48b685">&#39;%s\r\n&#39;</span> <span style="color:#48b685">&#34;gemini://huc.fr.eu.org&#34;</span> | vger -v -d /var/gemini 
</span></span><span style="display:flex;"><span><span style="color:#f99b15">20</span> text/gemini; 
</span></span><span style="display:flex;"><span><span style="color:#776e71"># huc.fr.eu.org|gemini</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><ul>
<li>Si la réponse est similaire, c&rsquo;est que vger écoute bien en local !</li>
<li>Si vous avez pour réponse <code>telnet: Unable to connect to remote host: Connection refused</code>,
c&rsquo;est certainement soit que le service <code>inetd</code> ne peut répondre - est-il
actif ? ou qu&rsquo;il y a un problème dans sa configuration. Vérifiez !</li>
</ul>
<hr>
<p>⇒ Vérifier que le port 1965 soit ouvert en écoute sur vos adresses IP :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ netstat -an | grep <span style="color:#f99b15">1965</span>
</span></span><span style="display:flex;"><span>tcp          <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span>  *.1965                 *.*                    LISTEN
</span></span><span style="display:flex;"><span>tcp          <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span>  46.23.90.29.1965       *.*                    LISTEN
</span></span><span style="display:flex;"><span>tcp6         <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span>  2a03:6000:6e65:6.1965  *.*                    LISTEN
</span></span><span style="display:flex;"><span>tcp6         <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span>  *.1965                 *.*                    LISTEN
</span></span></code></pre></div><hr>
<p>⇒ Pour finir, vous pouvez vérifier avec l&rsquo;outil <code>telnet</code> sur le port 1965,
en local et depuis une autre machine que le service écoute.</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>l&rsquo;article de Solène à-propos de <a href="https://dataswamp.org/~solene/2021-02-24-nginx-stream.html" rel="external">
Nginx as a TCP/UDP relay</a> <em>- en anglais</em></li>
<li>la documentation du protocol Gemini : <a href="https://gemini.circumlunar.space/docs/" rel="external">https://gemini.circumlunar.space/docs/</a> <em>- en anglais</em></li>
<li><a href="https://openports.pl/path/security/letsencrypt/client" rel="external">Readme du paquet certbot</a></li>
</ul>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/pledge.4" title="Page du Manuel OpenBSD pour : pledge">pledge(4)</a>
, 
<a class="man" href="https://man.openbsd.org/unveil.4" title="Page du Manuel OpenBSD pour : unveil">unveil(4)</a>
</li>
<li>une fois installé le manpage : <code>man 8 vger</code></li>
<li>le fichier pkg-readme dans <code>/usr/local/share/doc/pkg-readmes/vger</code></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer le serveur V&#39;Ger, pour voyager sur le protocol Gemini]]></summary>
        <published>2022-05-01T12:12:22+02:00</published>
        <updated>2023-12-18T19:20:06+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c10ec14e-2e36-c3d8-9b34-c9ae7c3e327d</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/iblock-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iblock : bloqueur de connexions TCP indésirables, sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <category term="TCP" scheme="http://doc.huc.fr.eu.org/fr/tags/tcp/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="inetd" scheme="http://doc.huc.fr.eu.org/fr/tags/inetd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>iblock</strong> est un logiciel dont le but est de détecter
des connexions TCP, sur des ports précis, afin de bloquer les adresses IP
correspondantes par le biais du parefeu Packet Filter, sous OpenBSD.</p>
<p>Le service inetd est chargé de l&rsquo;écoute active.</p>
<ul>
<li>Auteure du projet : Solène Rapenne</li>
<li>URL du dépôt Git : <a href="https://tildegit.org/solene/iblock.git" rel="external">https://tildegit.org/solene/iblock.git</a></li>
<li>liste d&rsquo;URL bannies : <a href="http://perso.pw/blocklist.txt" rel="external">http://perso.pw/blocklist.txt</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Commençons par la copie du dépôt Git :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ git clone https://tildegit.org/solene/iblock.git
</span></span><span style="display:flex;"><span>:$ cd iblock
</span></span></code></pre></div><p>Compilons le binaire - <em>OpenBSD renferme nativement les outils adéquats</em> - :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas make
</span></span><span style="display:flex;"><span>cc -o iblock main.c
</span></span><span style="display:flex;"><span>; vérifions la présence du binaire
</span></span><span style="display:flex;"><span>$ ls -al iblock
</span></span><span style="display:flex;"><span>-rwxr-xr-x  <span style="color:#f99b15">1</span> root  moi  <span style="color:#f99b15">8496</span> Apr <span style="color:#f99b15">10</span> 12:23 iblock*
</span></span></code></pre></div><p><em>Si la phase de compilation s&rsquo;exécute mal, contactez Solène !</em></p>
<p>Solène n&rsquo;a pas créé la cible &ldquo;install&rdquo;, donc copions le binaire dans le
répertoire cible :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas cp iblock /usr/local/bin/
</span></span><span style="display:flex;"><span>$ ls -al /usr/local/bin/iblock
</span></span><span style="display:flex;"><span>-rwxr-xr-x  <span style="color:#f99b15">1</span> root  wheel  <span style="color:#f99b15">8496</span> Apr <span style="color:#f99b15">10</span> 12:26 /usr/local/bin/iblock*
</span></span></code></pre></div><p>Passons maintenant à la phase de configuration !</p>
<h2 id="configuration">Configuration</h2>
<h3 id="utilisateur-dédié-_iblock">Utilisateur dédié _iblock</h3>
<p>Créons en tout premier un utilisateur dédié, nommé <strong>_iblock</strong> :</p>
<p><code>:$ doas useradd -s /sbin/nologin _iblock</code></p>
<h3 id="doas">doas</h3>
<ul>
<li>Fichier de configuration : <code>/etc/doas.conf</code></li>
</ul>
<p>Ajoutons la règle suivante dans le fichier de configuration de <code>doas</code> pour
autoriser l&rsquo;utilisateur dédié à utiliser l&rsquo;outil <code>pfctl</code> :</p>
<p><code>permit nopass _iblock cmd /sbin/pfctl</code></p>
<h3 id="inetd">inetd</h3>
<ul>
<li>Fichier de configuraton : <code>/etc/inetd.conf</code></li>
</ul>
<p>Configurons maintenant le service <strong>inetd</strong> :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">666 stream tcp nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
666 stream tcp6 nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
</code></pre><ul>
<li>le port <strong>666</strong> est utilisé - <em>bien sûr, vous pouvez le changer</em>.</li>
<li>géré par l&rsquo;utilisateur <strong>_iblock</strong>, appelant le binaire <code>iblock</code>.</li>
<li>le dernier argument est le nom du paramètre qui est ajouté aux adresses
IP qui sont enregistrées dans la table gérée par PF.</li>
</ul>
<p>Et activons et démarrons le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas rcctl enable inetd <span style="color:#5bc4bf">&amp;&amp;</span> doas rcctl start inetd
</span></span></code></pre></div><h3 id="shutdown">shutdown</h3>
<p>En premier, créons un fichier de &ldquo;secours&rdquo; pour rendre la future table
dans PF persistante à l&rsquo;extinction et au redémarrage du serveur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# touch /etc/pf-blocked_tcp.txt
</span></span></code></pre></div><p>Puis créons/modifions le fichier <code>/etc/rc.shutdown</code> pour y ajouter :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">pfctl -t blocked_tcp -T show &gt; /etc/pf-blocked_tcp.txt
</code></pre><h3 id="pf">PF</h3>
<p>Voici un exemple de règles à ajouter à PF :</p>
<ol>
<li>
<p>déclaration d&rsquo;une variable, ici nommée <strong>block_tcp_ports</strong>, soit un ensemble
de ports à surveiller</p>
</li>
<li>
<p>création d&rsquo;une table persistante, ici nommée <strong>blocked_tcp</strong></p>
</li>
<li>
<p>règle bloquante, portant le label <strong>iblock</strong></p>
</li>
<li>
<p>les deux dernières règles analysent le flux TCP, sur les
protocoles IPv4 et IPv6, en &ldquo;écoutant&rdquo; les ports enregistrés dans la
variable <strong>block_tcp_ports</strong>, puis redirigent sur l&rsquo;interface locale,
à destination du port <strong>666</strong>.</p>
</li>
</ol>
<pre tabindex="0"><code class="language-conf" data-lang="conf">block_tcp_ports = &#34;{ 21 23 111 135 137:139 445 1433 3306 3389 5432 6000:6010 7890 9999 25565 27019 }&#34;

table &lt;blocked_tcp&gt; persist file &#34;/etc/pf-blocked_tcp.txt&#34;

### iblock: block all in table
block in quick from &lt;blocked_tcp&gt; label iblock

### iblock: redirect to inetd service on localhost
pass in quick on egress inet  proto tcp to port $block_tcp_ports rdr-to 127.0.0.1 port 666
pass in quick on egress inet6 proto tcp to port $block_tcp_ports rdr-to ::1       port 666
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Les ports analysés, par défaut, sont FTP, telnet, DNS, RPC, SMB,
MSSQL, MySQL, RDP, PostgreSQL, Minecraft, Steam. <br>
J&rsquo;ai rajouté : X11, Goaccess, pfstat ; <em>à vous de rajouter…</em></div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si vous hébergez un service, tel que DNS, vous allez bloquer
toutes les connexions, car par défaut, le port 53 adéquat est analysé
pour être bloqué. <br>
<em>(cette remarque vaut pour tout service que vous hébergez !)</em></div>

<p>Pensez à faire recharger le jeu de règles par PF : <br>
<code>$ doas pfctl -f /etc/pf.conf</code></p>
<h2 id="surveillance">Surveillance</h2>
<blockquote>
<p>Mais qui surveille ?</p>
</blockquote>
<p>⇒ L&rsquo;activité est enregistrée dans les deux logs &lsquo;daemon&rsquo; et &lsquo;messages&rsquo;.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ grep iblock /var/log/messages
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:26:38 sh1 iblock: blocking 46.23.148.71
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:30:28 sh1 iblock: blocking 180.225.98.236
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:31:48 sh1 iblock: blocking 46.23.157.246
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:32:43 sh1 iblock: blocking 95.57.218.103
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:36:00 sh1 iblock: blocking 103.89.91.158
</span></span><span style="display:flex;"><span>Apr <span style="color:#f99b15">10</span> 12:38:41 sh1 iblock: blocking 23.128.248.41
</span></span></code></pre></div><p>⇒ De même, l&rsquo;outil <code>pfctl</code> peut nous montrer les différentes adresses IP
enregistrées dans la table, gérée par PF :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas pfctl -t blocked_tcp -T show
</span></span><span style="display:flex;"><span>   23.128.248.41
</span></span><span style="display:flex;"><span>   46.23.148.71
</span></span><span style="display:flex;"><span>   46.23.157.246
</span></span><span style="display:flex;"><span>   95.57.218.103
</span></span><span style="display:flex;"><span>   103.89.91.158
</span></span><span style="display:flex;"><span>   180.225.98.236
</span></span></code></pre></div><p>voire de l&rsquo;utiliser pour connaître les statistiques liées - <em>pour comprendre
ces informations, merci de lire le <a href="https://man.openbsd.org/pfctl#s~8" rel="external">manpage de l&rsquo;outil</a>
pour connaître la signification du colonnage</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas pfctl -sl | grep iblock
</span></span><span style="display:flex;"><span>iblock <span style="color:#f99b15">44666</span> <span style="color:#f99b15">1188</span> <span style="color:#f99b15">58504</span> <span style="color:#f99b15">1188</span> <span style="color:#f99b15">58504</span> <span style="color:#f99b15">0</span> <span style="color:#f99b15">0</span> <span style="color:#f99b15">0</span>
</span></span></code></pre></div><p>⇒ Il est possible de surveiller l&rsquo;activité de l&rsquo;utilisateur <strong>_iblock</strong>
avec - <em>mais dans ce cas, franchement peu utile</em> :</p>
<ul>
<li><code>top -U _iblock</code></li>
<li><code>fstat -u _iblock -n</code></li>
<li><code>ps aux -U _iblock</code></li>
</ul>
<h3 id="munin">munin</h3>
<p>Si vous souhaitez obtenir des statistiques avec <a class="tag" href="/fr/tags/munin">munin</a>
,
Solène m&rsquo;a fournit un script, à exécuter avec les droits de l&rsquo;utilisateur
<strong>_munin</strong>, tel que :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">#!/bin/sh

if [ &#34;$1&#34; = &#34;config&#34; ]; then
        echo &#34;graph_title Banned IP absolute number&#34;
        echo &#34;graph_vlabel gauge&#34;
        echo &#34;a1.label value&#34;
        exit 0
fi

printf &#34;a1.value &#34;
doas /sbin/pfctl -t blocked_tcp -T show | sort -n -u | awk &#39;END { print NR }&#39;
</code></pre><p>Ce qui nécessite de modifier la configuration de <a href="/fr/monitor/iblock-openbsd/#doas">doas</a> pour autoriser
l&rsquo;utilisateur <strong>_munin</strong> à utiliser l&rsquo;outil <code>pfctl</code>, tel que :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">:# iblock: auth _munin-plugin to use pfctl
permit nopass _munin-plugin cmd /sbin/pfctl args -t blocked_tcp -T show
</code></pre><hr>
<p>Ci-dessous, voici une image de statistiques d&rsquo;adresses IP bloquées, restituée
par Solène, en date du 10/04/2022 :</p>
<figure>
    <a href="/images/monitor/iblock-stats.png" title="Statistiques d&#39;adresses IP bloquées grâce à iblock">
    <picture>
        
        <source srcset="/images/monitor/iblock-stats_hu_f5825dfa88eb4837.webp" type="image/webp">
        
        <img alt="Statistiques d&#39;adresses IP bloquées grâce à iblock" height="142" loading="lazy" src="/images/monitor/iblock-stats_hu_67ff3052dd3359a4.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Statistiques d'adresses IP bloquées grâce à iblock</figcaption>
</figure>
<h2 id="dépannage">Dépannage</h2>
<p>Dans les logs &lsquo;daemon&rsquo; et &lsquo;messages&rsquo;, vous retrouvez le message suivant :</p>
<p><code>inetd[69849]: execv /usr/local/bin/iblock: No such file or directory</code></p>
<p><strong>Assurez-vous d&rsquo;avoir compiler puis copier le binaire iblock dans le
répertoire en question !</strong></p>
<hr>
<p>Voilà !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[iblock est un outil pour bloquer des connexions TCP indésirables, conjointement au parefeu d&#39;OpenBSD, Packet-Filter, utilisant le service inetd.]]></summary>
        <published>2022-04-10T22:34:06+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:819fb7f4-d53e-d397-75ba-dc74f8c127f0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sshlockout/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: sshlockout : protéger le serveur SSH, sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Surveillance" scheme="http://doc.huc.fr.eu.org/fr/tags/surveillance/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>sshlockout</strong> est un petit outil logiciel bien pratique pour surveiller
les connexions sur le service SSH. Il gardera une trace des tentatives
de connexions par des utilisateurs inconnus aussi bien que des erreurs
d&rsquo;authentification.</p>
<p>Au bout de 5 tentatives sur une période d&rsquo;une heure, une entrée permanente
est ajoutée à la table associée aux adresses IP par pf(4).</p>
<p><em>En deux, trois minutes d&rsquo;installation et de configuration, voici un système
de surveillance, géré avec le parefeu, efficace et fonctionnel !</em></p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>sshlockout</strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="packet-filter">Packet-Filter</h3>
<p>Il faut ajouter/modifier vos règles du parefeu Packet-Filter :</p>
<ol>
<li>une table persistante, nommée <strong>lockout</strong>, telle que : <br>
<code>table &lt;lockout&gt; persist</code></li>
<li>puis l&rsquo;équivalent de cette règle bloquante : <br>
<code>block in quick on egress proto tcp from &lt;lockout&gt; to port ssh</code></li>
</ol>
<h3 id="etcsyslogconf">/etc/syslog.conf</h3>
<p>Il est nécessaire de modifier le fichier de configuration <code>/etc/syslog.conf</code>,
en ajoutant la déclaration suivante :</p>
<p><code>auth.info;authpriv.info | exec /usr/bin/doas -n /usr/local/sbin/sshlockout -pf &quot;lockout&quot;</code></p>
<h3 id="cron">cron</h3>
<p>Pour finir, il faut ajouter une tâche cron, pour libérer les adresses IP
de la table <strong>lockout</strong>, dont l&rsquo;enregistrement est vieux de plus d&rsquo;un jour.</p>
<p>Le manpage officiel informe de mettre dans la cron-table de root :
<code>3 3 * * *  pfctl -t lockout -T expire 86400</code></p>
<hr>
<p>Personnellement, je préfère ajouter à mon fichier <strong>daily.local</strong>, l&rsquo;écriture
suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">## sshlockout: expire IP</span>
</span></span><span style="display:flex;"><span>pfctl -t lockout -T expire <span style="color:#f99b15">84600</span>
</span></span><span style="display:flex;"><span>printf <span style="color:#48b685">&#39;%s\n&#39;</span> <span style="color:#48b685">&#34;=&gt; Nb IPs into lockout table:&#34;</span>
</span></span><span style="display:flex;"><span>pfctl -t lockout -T show | wc -l
</span></span></code></pre></div><p><em>ce qui libére les adresses IP enregistrées depuis une journée, et me
restitue dans le mail quotidien le nombre d&rsquo;IP enregistrées dans la table.</em></p>
<hr>
<p>Voilà !</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>le manpage, une fois installé : <code>man 8 sshlockout</code></li>
<li>gestion des tables dans Packet-Filter :
<ul>
<li><a href="https://www.openbsd.org/faq/pf/tables.html" rel="external">https://www.openbsd.org/faq/pf/tables.html</a></li>
<li><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/pf/tables" rel="external">https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/pf/tables</a></li>
</ul>
</li>
<li>
<a class="man" href="https://man.openbsd.org/daily.8" title="Page du Manuel OpenBSD pour : daily">daily(8)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment protéger le serveur SSH des abus de connexions, sous OpenBSD, avec l&#39;outil sshlockout]]></summary>
        <published>2022-04-03T08:01:04+02:00</published>
        <updated>2023-05-02T16:04:51+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:edd6ef9b-beea-7301-a04b-1c20a44b97b0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sshfs/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SshFS : Monter un répertoire à distance par connexion SSH / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="sshfs" scheme="http://doc.huc.fr.eu.org/fr/tags/sshfs/" />
        <category term="fuse" scheme="http://doc.huc.fr.eu.org/fr/tags/fuse/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://fuse.sourceforge.net/sshfs.html" rel="external">SSHFS</a></strong> permet de monter un
répertoire à distance dans une connexion ssh normale.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>sshfs-fuse</code></strong>.</p>
<h3 id="depuis-openbsd-60">Depuis OpenBSD 6.0</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Avec la version 6.0, la variable système <code>kern.usermount</code> -
<em>[sysctl(3)]http://man.openbsd.org/OpenBSD-5.9/man3/sysctl.3)</em> - n&rsquo;est
plus gérée… d&rsquo;où la nécessité d&rsquo;utiliser des droits d&rsquo;administration, tel
que par <a href="https://man.openbsd.org/doas" rel="external">doas(1)</a> !</div>

<h2 id="utilisation">Utilisation</h2>
<p><strong>Pour monter</strong>, un répertoire à distance, depuis une machine faisant
fonctionner le service SSH, sur votre station :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas sshfs -o <span style="color:#ef6155">compression</span><span style="color:#5bc4bf">=</span>yes -o <span style="color:#ef6155">port</span><span style="color:#5bc4bf">=</span>numero_de_port -o allow_other -o <span style="color:#ef6155">uid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -u <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> -o <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -g <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> identifiant@hote_distant:/repertoire_cible /point_de_montage
</span></span></code></pre></div><p>Explications sur les options possibles :</p>
<ul>
<li><code>-o compression=yes</code> peut être remplacée par l&rsquo;option <code>-C</code> - <em>option
peu nécessaire</em></li>
<li><code>-o port=numero_de_port</code> : le numéro du port SSH à contacter sur la
machine distante ; si c&rsquo;est le port par défaut, à savoir 22, il n&rsquo;y
a pas besoin de spécifier l&rsquo;option &lsquo;port&rsquo;… cette option peut tout
simplement être remplacée par l&rsquo;option <code>-p numero_de_port</code></li>
<li>les options <code>-o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER)</code>
vous permettront d&rsquo;avoir accès localement aux données montées.</li>
<li>l&rsquo;option <code>allow_other</code> nécessite l&rsquo;ajout de l&rsquo;option <code>user_allow_other</code>
dans le fichier <code>/etc/fuse.conf</code>
<ul>
<li><em>si ce dernier n&rsquo;est pas créé, faites-le</em>…</li>
</ul>
</li>
<li><code>identifiant</code> : votre identifiant sur la machine distante</li>
<li><code>hote_distant</code> : le nom FQDN ou l&rsquo;adresse IP de la machine distante.</li>
<li><code>repertoire_cible</code> : le répertoire, sur la machine distante, que vous
souhaitez pouvoir atteindre. Selon les paramètres de configuration
du serveur SSH, vous ne pourrez très certainement pas monter plus
haut que votre partition <code>/home</code>. Si vous ne spécifiez rien, tel que
<code>id@hote:</code>, alors sshfs se connectera à votre répertoire <code>/home</code>.</li>
<li><code>point_de_montage</code> : l&rsquo;endroit où vous désirez que le répertoire
distant se connecte sur votre station de travail.</li>
</ul>
<hr>
<p><strong>Pour démonter</strong> le point de montage :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas umount /point_de_montage
</span></span></code></pre></div><hr>
<h2 id="astuce">Astuce</h2>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si vous utilisez un environnement graphique, tel que Xfce, préférez
l&rsquo;usage de <a class="inside" href="/fr/sys/openbsd/gigolo/" title="Lien interne vers l&#39;article : 'Gigolo / OpenBSD'">Gigolo</a>
, en créant
un signet SSH… car il ne nécessite pas l&rsquo;usage de doas !</div>

<hr>
<h2 id="documentation">Documentation</h2>
<p>Il peut vous être utile de lire localement sur votre station de travail OpenBSD, la page de manuel correspondante <code>man sshfs</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Monter sous OpenBSD un répertoire distant sur le système de fichier local, en SSH, grâce à l&#39;outil SSHFS.]]></summary>
        <published>2022-01-19T15:33:07+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a3501605-0f67-1fd2-f601-1bd098a8736d</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/goaccess-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Goaccess / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <category term="dataviz" scheme="http://doc.huc.fr.eu.org/fr/tags/dataviz/" />
        <category term="log" scheme="http://doc.huc.fr.eu.org/fr/tags/log/" />
        <category term="goaccess" scheme="http://doc.huc.fr.eu.org/fr/tags/goaccess/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Goaccess</strong> est un logiciel libre, réputé pour être léger, rapide, afin
d&rsquo;analyser en temps réel ou non l&rsquo;activité sur un serveur web, soit directement
au sein d&rsquo;un terminal Unix, soit sur le protocol HTTPS.</p>
<p>Il est capable de produire des statitisques au format HTML, JSON, voire CSV.</p>
<hr>
<p>⇒ Environnement :</p>
<ul>
<li>OpenBSD : <del>6.9</del> → 7.1</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Classique : <code>:# pkg_add goaccess</code></p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration principal est : <code>/etc/goaccess/goaccess.conf</code>.</li>
</ul>
<hr>
<p>⇒ Il est possible sans aucun soucis d&rsquo;utiliser goaccess avec son fichier de
configuration sans rien modifier. <br>
Cela nécessite de passer toutes les options nécessaires dans la ligne de
commande, hors certaines options sont clairement communes et peuvent être
&ldquo;figées&rdquo; dans la configuration commune.</p>
<p>⇒ Il est aussi possible de créer plusieurs fichiers de configuration, chacun
spécifique à un domaine web et de paramètrer selon le domaine. Dans ce cas-là,
il faudra cibler tel fichier de configuration.</p>
<p><em>Dans la suite de cet article, j&rsquo;utilise un seul fichier de configuration,
et je cible quelques options dans la ligne de commande.</em></p>
<p>Voyons les principales options de configuration :</p>
<h3 id="time-date-format">Time, Date format</h3>
<p>Le formatage de l&rsquo;heure !</p>
<p>⇒ Si vous utilisez le service <strong>httpd</strong>, il faudra faire attention à
paramètrer correctement le style de log dans son propre fichier de
configuration, et de le répercuter dans le fichier de configuration
de goaccess dans la section <strong>Time Format Options</strong>.</p>
<ul>
<li>pour <a href="https://man.openbsd.org/httpd.conf.5#style" rel="external">httpd.conf</a>(5)#style</li>
</ul>
<p>⇒ Pour <strong>nginx</strong>, il suffira de décommenter les options suivantes :</p>
<ul>
<li><code>time-format %H:%M:%S</code></li>
<li><code>date-format %d/%b/%Y</code> - ce dernier étant dans la section <strong>Date Format Options</strong></li>
</ul>
<h3 id="log-format">Log format</h3>
<ul>
<li><code>log-format</code> : préférez le format <strong>COMBINED</strong> - <em>sauf si concernant httpd,
vous en restez au format <strong>common</strong>, dans ce cas choisissez l&rsquo;équivalent</em>.</li>
</ul>
<p><em>Si vous utilisez <strong>nginx</strong>, il est impératif d&rsquo;enregistrer tous les statuts,
de ne pas filter les statuts 2xx et 3xx - si vous aviez créer une directive
<strong>map</strong> en ce sens, il vous faudra à minima la commenter puis relancer le
service web</em>.</p>
<h3 id="file-options">File Options</h3>
<p>Si vous n&rsquo;avez qu&rsquo;un seul domaine web sur votre serveur à analyser, il
est utile de paramètrer l&rsquo;option <strong>log-file</strong> vers le chemin absolu du
fichier <strong>access.log</strong> relatif.</p>
<h3 id="parse-options">Parse Options</h3>
<ul>
<li>
<p><code>exclude-ip</code> : n&rsquo;hésitez pas à utiliser cette option pour exclure de
l&rsquo;analyse soit des adresses IP, soit des segments réseaux, <em>tel votre
réseau personnel, si votre serveur est par exemple à domicile</em>.</p>
</li>
<li>
<p><code>444-as-404</code> : l&rsquo;erreur 444 est spécifique au serveur Nginx. À vous
de voir, si vous voulez que ces erreurs soient considérées comme étant
des entrées d&rsquo;erreur 404. Si oui, changez la en <strong>true</strong>.</p>
</li>
<li>
<p><code>ignore-crawlers</code> : afin d&rsquo;ignorer les robots ; changez la à <strong>true</strong></p>
</li>
<li>
<p><code>ignore-panel</code> est un ensemble de panneau qui peut être désactivé
<em>(voire activé)</em> ; pour des histoires de RGPD, mieux vaut désactiver
le panneau <strong>REMOTE_USER</strong></p>
</li>
<li>
<p><code>anonymize-ip</code> : changez-la à <strong>true</strong> - <em>en ces temps de RGPD, il vaut mieux !</em></p>
</li>
</ul>
<h3 id="persistence-options">Persistence Options</h3>
<ul>
<li><code>db-path</code> : le chemin /absolu vers la base de données de goaccess -
à ne configurer que s&rsquo;il y a un seul domaine.</li>
<li><code>persist</code> : permet d&rsquo;enregistrer les données analysées</li>
<li><code>restore</code> : charge les données à visualiser depuis les données enregistrées.</li>
</ul>
<p>⇒ Activer les deux dernières options en positionnant sur <strong>true</strong>, si vous
voulez garder les enregistrements de l&rsquo;analyse dans la base de donnée de
goaccess.</p>
<hr>
<p>Alors, bien sûr, comme vous le verrez, il existe beaucoup d&rsquo;autres options.
À vous de voir…</p>
<p>Ensuite il suffit d&rsquo;<a href="/fr/monitor/goaccess-openbsd/#utilisation-basique">utiliser basiquement</a> le binaire
<strong>goaccess</strong>.</p>
<hr>
<p>Maintenant, poussons un peu plus la configuration :</p>
<h3 id="utilisateur-dédié">Utilisateur dédié</h3>
<p>Personnellement je préfère créer et utiliser un utilisateur système dédié.
Parmi les avantages, citons la recherche dans les log messages, voire cron.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# useradd -s /sbin/nologin -d /var/db/goaccess _goaccess
</span></span></code></pre></div><hr>
<p>⇒ la recherche dans les logs se faisant ainsi :</p>
<p><code>:$ grep goaccess /var/log/messages</code> ou <br>
<code>:$ doas grep _goaccess /var/cron/log</code></p>
<h4 id="doas">doas</h4>
<p>⇒ J&rsquo;ai préféré ajouter l&rsquo;autorisation d&rsquo;utiliser le binaire <strong>goaccess</strong>
à l&rsquo;utilisateur <strong>_goaccess</strong>.</p>
<p>Ajoutez à votre fichier <code>/etc/doas.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">permit nopass _goaccess cmd /usr/local/bin/goaccess</span>
</span></span></code></pre></div><p><em>(J&rsquo;avoue, je ne suis pas sûr que ce soit réellement nécessaire car le binaire
goaccess semble s&rsquo;exécuter sans droit particulier)</em>.</p>
<h4 id="répertoire-de-la-base-de-données">Répertoire de la base de données</h4>
<p>⇒ Création du répertoire principal pour la base de données de goaccess :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /var/db/goaccess
</span></span><span style="display:flex;"><span>:# chown _goaccess:daemon /var/db/goaccess
</span></span></code></pre></div><p><em>(personnellement, j&rsquo;ai préféré un autre chemin absolu)</em>.</p>
<p><strong>Pensez à ajouter ce répertoire dans vos sauvegardes !</strong></p>
<hr>
<p>Ensuite si comme moi, vous avez plusieurs domaines web sur votre serveur,
créez autant de sous-répertoire portant le nom du domaine web, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ <span style="color:#ef6155">domain</span><span style="color:#5bc4bf">=</span>
</span></span><span style="display:flex;"><span>:$ doas -u _goaccess mkdir <span style="color:#48b685">&#34;/var/db/goaccess/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><p>Ainsi, les futures statistiques seront vraiment dédiés à un domaine…</p>
<h4 id="crontab">crontab</h4>
<p>⇒ Il ne reste plus qu&rsquo;à ajouter autant de règles cron que nécessaire, tel
que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas -u _goaccess crontab -e
</span></span></code></pre></div><p><em>(Il est possible d&rsquo;appeler la crontab utilisateur, tel que : <br>
<code>doas crontab -u _goaccess -e</code>)</em>.</p>
<p>Pour ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">*/15 * * * * -ns goaccess -a --db-path &#34;/var/db/goaccess/domain/&#34; -f /var/www/logs/domain/access.log -o /var/www/goaccess/domain/stats.html</span>
</span></span></code></pre></div><p>Petites explications :</p>
<ul>
<li>une tâche cron programmée pour être exécutée tous les quarts d&rsquo;heure.
<em>Gardez à l&rsquo;esprit que c&rsquo;est un exemple</em>.</li>
<li>remplacez la chaine &lsquo;<em>domain</em>&rsquo; par le nom de domaine web…</li>
</ul>
<h3 id="authentification-requise">Authentification requise</h3>
<p>À vous de voir si vous désirez une authentification web avant la consultation
des pages HTML ; d&rsquo;aucuns estiment qu&rsquo;il le faut, d&rsquo;autres non ; personnellement
je préfère.</p>
<p>Après l&rsquo;utilisation du binaire <strong>htpasswd</strong>, elle se configure au-niveau
du fichier de configuration de votre serveur web.</p>
<ul>
<li>pour httpd, c&rsquo;est la directive <strong>authenticate</strong> qui servira.</li>
<li>pour nginx, ce sont les directives <strong>auth_basic</strong> et <strong>auth_basic_user_file</strong>
qui répondront au besoin.</li>
</ul>
<h4 id="configuration-httpd">Configuration httpd</h4>
<p>De manière basique :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">server &#34;domain.tld&#34; {

(…)

    root &#34;/htdocs/domain.tld/www&#34;

    location &#34;/stats&#34; {
        authenticate with &#34;/file_htpwd&#34;
        directory auto index
    }

(…)

}
</code></pre><p>Ne pas oubliez que le chemin du fichier htpasswd est relatif au chroot web !</p>
<h4 id="configuration-nginx">Configuration nginx</h4>
<p>Idem, basiquement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> <span style="color:#48b685">/stats/</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">auth_basic</span> <span style="color:#48b685">&#34;Auth</span> <span style="color:#48b685">Area&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">auth_basic_user_file</span> <span style="color:#48b685">/file_htpwd</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">autoindex</span> <span style="color:#ef6155">on</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">(…)</span>
</span></span></code></pre></div><hr>
<p>Voilà pour la partie &ldquo;configuration&rdquo; !</p>
<hr>
<h2 id="utilisation">Utilisation</h2>
<h3 id="utilisation-basique">Utilisation basique</h3>
<p>Basiquement le binaire s&rsquo;exécute ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ goaccess -o /var/www/htdocs/domain.tld/stats/index.html
</span></span></code></pre></div><h3 id="par-lutilisateur-dédié">Par l&rsquo;utilisateur dédié</h3>
<p>⇒ Une fois configuré, goaccess s&rsquo;utilise ainsi :</p>
<p>Par exemple, une première fois, en précisant une date de mois-année :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ <span style="color:#ef6155">domain</span><span style="color:#5bc4bf">=</span>
</span></span><span style="display:flex;"><span>:$ <span style="color:#ef6155">date</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>date +<span style="color:#48b685">&#39;%Y-%m&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>:$ doas -u _goaccess goaccess -a --db-path <span style="color:#48b685">&#34;/var/db/goaccess/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">/&#34;</span> -f <span style="color:#48b685">&#34;/var/www/logs/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">/access.log&#34;</span> -o <span style="color:#48b685">&#34;/var/db/goaccess/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">/stats-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">date</span><span style="color:#f99b15">}</span><span style="color:#48b685">.html&#34;</span>
</span></span></code></pre></div><hr>
<p>Je me suis créé un script shell pour me faciliter la vie - nommé <strong>goaccess.sh</strong> :</p>
<pre tabindex="0"><code class="language-file" data-lang="file">#!/bin/sh

###
#
# générer les stats du domain
#
##

date=&#34;$(date +&#39;%m-%Y&#39;)&#34;
dir_db=&#34;/var/db/goaccess&#34;
domain=&#34;$1&#34;

if [ -z &#34;${domain}&#34; ]; then
    printf &#39;%s %s\n&#39; &#34;KO&#34; &#34;No domain. Script stops!&#34;
    logger &#34;$0: no domain found as option; script stops!&#34;
    exit 1
fi

if [ ! -d &#34;${dir_db}/${domain}/&#34; ]; then
    printf &#39;%s %s\n&#39; &#34;KO&#34; &#34;The destination directory &#39;${dir_db}/${domain}/&#39; seems not exist!&#34;
    logger &#34;$0: The destination directory for goaccess not exists; script stops!&#34;
    exit 2
fi

goaccess -a --db-path &#34;${dir_db}/${domain}/&#34; -f &#34;/var/www/logs/${domain}/access.log&#34; -o &#34;${dir_db}/${domain}/stats-${domain}-${date}.html&#34;
</code></pre><p>Puis modifié la crontab de l&rsquo;utilisateur <strong>_goaccess</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">*/15 * * * * -ns /repertoire/goaccess.sh domain-x.tld</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">0    * * * * -ns /repertoire/goaccess.sh domain-y.tld</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">0    0 * * * -ns /repertoire/goaccess.sh domain-z.tld</span>
</span></span></code></pre></div><p><em>(chacun à des moments différents)</em>.</p>
<hr>
<p>Et non ce n&rsquo;est pas fini !</p>
<p>En effet, le fichier d&rsquo;analyse HTML généré est écrit dans le répertoire
de base de données dédié. L&rsquo;utilisateur <strong>_goaccess</strong> n&rsquo;a pas accès au(x)
répertoire(s) web, et n&rsquo;a pas avoir accès.</p>
<p>Par contre, il est possible de demander à l&rsquo;utilisateur web <strong>www</strong> de copier
le fichier de statistiques HTML pour le déposer dans le répertoire web
correspondant.</p>
<p>Ainsi, j&rsquo;utilise le script shell suivant, nommé <strong>cp_stats.sh</strong> :</p>
<pre tabindex="0"><code class="language-file" data-lang="file">#!/bin/sh

set -e
#set -x

###
#
# copier les stats d&#39;un domaine pour les publier enligne
#
##

date=&#34;$(date +&#39;%m-%Y&#39;)&#34;
domain=&#34;$1&#34;
dir_db=&#34;/var/db/goaccess&#34;
dir_stats=&#34;/var/www/htdocs/${domain}/www/stats/&#34;

if [ -z &#34;${domain}&#34; ]; then
    printf &#39;%s %s\n&#39; &#34;KO&#34; &#34;No domain. Script stops!&#34;
    logger &#34;$0: no domain found as option; script stops!&#34;
    exit 1
fi

if [ ! -f &#34;${dir_db}/${domain}/stats-${domain}-${date}.html&#34; ]; then
    printf &#39;%s %s\n&#39; &#34;KO&#34; &#34;The needed file &#39;${dir_db}/${domain}/stats-${domain}-${date}.html&#39; not exists. Script stops!&#34;
    logger &#34;$0: The needed file &#39;${dir_db}/${domain}/stats-${domain}-${date}.html&#39; not exists; script stops!&#34;
    exit 2
fi

if [ ! -d &#34;${dir_stats}&#34; ]; then mkdir -p &#34;${dir_stats}&#34;; fi

cp &#34;${dir_db}/${domain}/stats-${domain}-${date}.html&#34; &#34;${dir_stats}&#34;
chown -R www &#34;${dir_stats}&#34;
</code></pre><p>Puis à modifier la crontab de l&rsquo;utilisateur web :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas -u www crontab -e
</span></span></code></pre></div><p>Tel que, pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">*/15 * * * * -ns /repertoire/cp_stats.sh domain-x.tld</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">5    * * * * -ns /repertoire/cp_stats.sh domain-y.tld</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">5    0 * * * -ns /repertoire/cp_stats.sh domain-z.tld</span>
</span></span></code></pre></div><h3 id="utilisation-temps-réel">Utilisation temps réel</h3>
<p>L&rsquo;utilisation temps réel se fait de deux manières possibles.</p>
<p>Dans ces contextes, nous n&rsquo;aurons pas besoin de l&rsquo;utilisateur dédié <strong>_goaccess</strong>.</p>
<h4 id="par-terminal">par terminal</h4>
<p>⇒ À minima, faites :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ goaccess -f /var/www/logs/<span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span>/access.log
</span></span></code></pre></div><p>Profitez de l&rsquo;esthétique vue basée sur les couleurs monokaï, par défaut.</p>
<h4 id="par-proxy-web">par proxy web</h4>
<p>Là, ça devient intéressant, mais un peu compliqué :</p>
<h5 id="proxy-httpd">proxy httpd</h5>
<p>Là, malheureusement, je n&rsquo;ai pas trouvé de solution. Voire avec relayd!</p>
<h5 id="proxy-nginx">proxy nginx</h5>
<p>Modifions la configuration du serveur en ajoutant une directive <strong>location</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> <span style="color:#48b685">/ws</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">proxy_pass</span> <span style="color:#48b685">http://localhost:7890</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">proxy_http_version</span> <span style="color:#f99b15">1</span><span style="color:#48b685">.1</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">proxy_set_header</span> <span style="color:#48b685">Upgrade</span> <span style="color:#ef6155">$http_upgrade</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">proxy_set_header</span> <span style="color:#48b685">Connection</span> <span style="color:#48b685">&#34;Upgrade&#34;</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h5 id="websocket">websocket</h5>
<p>Maintenant il faut exécuter goaccess avec les droits de l&rsquo;utilisateur <strong>www</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas -u www goaccess -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html --ws-url<span style="color:#5bc4bf">=</span>wss://huc.fr.eu.org:443/ws --port <span style="color:#f99b15">7890</span>
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">[</span>PARSING /var/www/logs/doc.huc.fr.eu.org/access.log<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">{</span>0<span style="color:#5bc4bf">}</span> @ <span style="color:#5bc4bf">{</span>0/s<span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>WebSocket server ready to accept new client connections
</span></span></code></pre></div><p>Remarquez que pour ce test, j&rsquo;ai :</p>
<ul>
<li>créer un nouveau fichier de configuration pour goaccess nommé
<strong>goaccess.realtime.conf</strong></li>
<li>je lui demande de créer le fichier HTML</li>
<li>et d&rsquo;écouter le serveur sur le websocket sécurisé</li>
</ul>
<p>Du fait d&rsquo;être obligé d&rsquo;utiliser l&rsquo;utilisateur web, nous pouvons en temps réel,
surveillez dans une console SSH, l&rsquo;activité de l&rsquo;utilisateur, avec des binaires
tels <strong>fstat</strong>, <strong>ps</strong>, par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ fstat -u www -n
</span></span><span style="display:flex;"><span>USER     CMD          PID   FD  DEV      INUM        MODE   R/W    SZ|DV
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>   wd  4,15   <span style="color:#f99b15">725760</span>        <span style="color:#f99b15">40755</span>    r      <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">0</span>  4,0     <span style="color:#f99b15">78329</span>        <span style="color:#f99b15">20620</span>   rw    5,0
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">1</span>  4,0     <span style="color:#f99b15">78329</span>        <span style="color:#f99b15">20620</span>   rw    5,0
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">2</span>  4,0     <span style="color:#f99b15">78329</span>        <span style="color:#f99b15">20620</span>   rw    5,0
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">3</span>  4,3       <span style="color:#f99b15">175</span>        <span style="color:#f99b15">10644</span>   rw        <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">4</span>  4,3       <span style="color:#f99b15">176</span>        <span style="color:#f99b15">10644</span>   rw        <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">5</span>  4,3       <span style="color:#f99b15">175</span>        <span style="color:#f99b15">10644</span>    w        <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">6</span>  4,3       <span style="color:#f99b15">176</span>        <span style="color:#f99b15">10644</span>    w        <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">7</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    <span style="color:#f99b15">8</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>    9* internet stream tcp 0x0 *:7890
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>   <span style="color:#f99b15">10</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>   <span style="color:#f99b15">11</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>www  goaccess   <span style="color:#f99b15">76729</span>   12* internet stream tcp 0x0 127.0.0.1:7890 &lt;-- 127.0.0.1:6459
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ ps aux -U www
</span></span><span style="display:flex;"><span>USER       PID %CPU %MEM   VSZ   RSS TT  STAT   STARTED       TIME COMMAND
</span></span><span style="display:flex;"><span>www   <span style="color:#f99b15">4071</span>  0.0  0.1  <span style="color:#f99b15">1572</span>  <span style="color:#f99b15">3488</span> ??  S      10:12AM    0:00.88 sshd: www@notty <span style="color:#5bc4bf">(</span>sshd<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>www  <span style="color:#f99b15">76729</span>  0.0  0.3 <span style="color:#f99b15">10096</span> <span style="color:#f99b15">12752</span> p0  S+      7:56PM    0:01.49 goaccess -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html /var/www/logs/do
</span></span></code></pre></div><p>Il ne reste plus qu&rsquo;à pointer un navigateur web le chemin du fichier <strong>realtime.html</strong>.</p>
<figure>
    <a href="/images/monitor/goaccess-realtime.png" title="dashboard goaccess real time">
    <picture>
        
        <source srcset="/images/monitor/goaccess-realtime_hu_9392cc2e2daef76c.webp" type="image/webp">
        
        <img alt="dashboard goaccess real time" height="36" loading="lazy" src="/images/monitor/goaccess-realtime_hu_cdf83e6b6bbb2dde.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>dashboard goaccess real time</figcaption>
</figure>
<p>Remarquez le petit point vert sous l&rsquo;icône en forme de roue crantée, en haut à gauche de l&rsquo;écran.</p>
<p><em>Il semble nécessaire de rafraîchir soit même la page ; au bout de temps
d&rsquo;un certain temps, elle perd le connecteur. Un petit coup de <kbd>F5</kbd>…</em></p>
<hr>
<p>Pour finir, on peut s&rsquo;amuser à exécuter goaccess en tant que service, soit
en utilisant l&rsquo;option <strong>&ndash;daemonize</strong>, soit en configurant le fichier de configuration dédiée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas -u www goaccess --daemonize -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html --ws-url<span style="color:#5bc4bf">=</span>wss://huc.fr.eu.org:443/ws --port <span style="color:#f99b15">7890</span>
</span></span><span style="display:flex;"><span>Daemonized GoAccess: <span style="color:#f99b15">48646</span>
</span></span></code></pre></div><p>Cette option <strong>ne fonctionne qu&rsquo;avec l&rsquo;option de temps réel</strong> active.</p>
<p>De même, il est <strong>impératif que l&rsquo;utilisateur web est accès au chemin qui
enregistrera le fichier de processus PID</strong> - autrement vous serez en échec ! <br>
Il faut donc paramètrer l&rsquo;option <strong>pid-file</strong> dans le fichier de configuratin.</p>
<p>Sous OpenBSD, pour rappel, du fait du chroot web, c&rsquo;est le répertoire
<code>/var/www/run</code> par défaut - <em>préférez un sous-répertoire dédié à l&rsquo;utilisateur
<strong>www</strong>.</em></p>
<hr>
<p>Bien-sûr, tout cela, c&rsquo;est pour le FUN, et l&rsquo;exemple ! :D</p>
<hr>
<p>Voilà !</p>
<p><em>(C&rsquo;est mon expérience… et la vôtre !?)</em></p>
<h2 id="dépannages">Dépannages</h2>
<p>Voici quelques erreurs rencontrées :</p>
<h3 id="permission-denied">Permission denied</h3>
<ul>
<li><code>Couldn't open file /var/db/goaccess/xxx/I32_DATES.db: Permission denied</code></li>
<li><code>Unable to open the specified pid file. Permission denied</code></li>
<li><code>Unable to open the specified pid file. Permission denied</code></li>
</ul>
<ol>
<li>goaccess ne peut pas écrire dans le répertoire en question !</li>
<li>Vérifiez que le répertoire cible existe…</li>
<li>Vérifiez les droits utilisateurs ; ils doivent impérativement correspondre
à celui de l&rsquo;utilisateur qui exécute goaccess : <code>_goaccess:daemon</code></li>
</ol>
<p>Ce problème est identique lors de la génération des fichiers HTML. Si les
droits ne sont pas attribués à l&rsquo;utilisateur <strong>_goaccess</strong>, vous ne pourrez
pas les générer.</p>
<p>Exemple de message d&rsquo;erreur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>GoAccess - version 1.5.1 - Sep <span style="color:#f99b15">26</span> <span style="color:#f99b15">2021</span> 14:08:19
</span></span><span style="display:flex;"><span>Config file: /etc/goaccess/goaccess.conf
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Fatal error has occurred
</span></span><span style="display:flex;"><span>Error occurred at: src/output.c - output_html - <span style="color:#f99b15">1183</span>
</span></span><span style="display:flex;"><span>Unable to open HTML file: Permission denied.
</span></span></code></pre></div><h3 id="error-opening-the-specified-maxmind-db-file">Error opening the specified MaxMind DB file</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>GoAccess - version 1.5.5 - Apr  <span style="color:#f99b15">8</span> <span style="color:#f99b15">2022</span> 09:03:43
</span></span><span style="display:flex;"><span>Config file: /etc/goaccess/goaccess.conf
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Fatal error has occurred
</span></span><span style="display:flex;"><span>Error occurred at: src/geoip2.c - init_geoip - <span style="color:#f99b15">89</span>
</span></span><span style="display:flex;"><span>Unable to open GeoIP2 database /var/db/GeoIP/GeoLite2-Country.mmdb: Error opening the specified MaxMind DB file
</span></span></code></pre></div><p>Vous avez activé certainement l&rsquo;option <code>geoip-database</code>.</p>
<p>Mais avez-vous téléchargé les fichiers nécessaires et installés dans le
répertoire <code>/var/db/GeoIP/</code> ?</p>
<h3 id="no-home-directory">No home directory</h3>
<ul>
<li><strong>Assurez-vous que le home directory déclaré pour l&rsquo;utilisateur dédié
existe bel et bien !</strong></li>
</ul>
<p>Puis vérifier l&rsquo;existence du chemin dans votre système de fichiers, sans
oublier que les droits utilisateurs correspondent bien à l&rsquo;utilisateur
dédié !</p>
<ul>
<li>Accessoirement, assurez-vous de la correspondance entre le home directory
de l&rsquo;utilisateur dédié ET la variable <code>dir_db</code> du script <code>goaccess.sh</code>.</li>
</ul>
<h2 id="documentations">Documentations</h2>
<ul>
<li>
<p><a href="https://www.geeek.org/goaccess-analyser-access-log/" rel="external">https://www.geeek.org/goaccess-analyser-access-log/</a> - où j&rsquo;ai piqué la
config de proxy nginx</p>
</li>
<li>
<p><a href="https://hautefeuille.eu/post/goaccess-openbsd/" rel="external">https://hautefeuille.eu/post/goaccess-openbsd/</a> : un autre exemple de
configuration pour httpd, juste pour de la consultation différée.</p>
</li>
<li>
<p><a href="https://www.arsouyes.org/blog/2020/20_Stats_Goaccess" rel="external">https://www.arsouyes.org/blog/2020/20_Stats_Goaccess</a></p>
</li>
</ul>
<h3 id="wikipédia">Wikipédia</h3>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Liste_des_codes_HTTP#4xx_-_Erreur_du_client_HTTP" title="Article Wikipédia : Liste_des_codes_HTTP">Liste_des_codes_HTTP : 4xx_-_Erreur_du_client_HTTP <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
<p><em><strong>Enjoy-ID!</strong></em> <br>
<em><strong>Enjoy-IT!</strong></em></p>
]]></content>
        <summary type="html"><![CDATA[Installer et utiliser Goaccess sur OpenBSD (avec des bouts de configuration pour les serveurs web httpd ou nginx)]]></summary>
        <published>2021-07-30T15:35:45+02:00</published>
        <updated>2025-11-11T15:44:28+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f03efc2f-4b6a-c81b-f816-6086e4a5d732</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/redirect-permanent-nginx-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Redirection permanente pour Nginx sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="redirection" scheme="http://doc.huc.fr.eu.org/fr/tags/redirection/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Comment faire une redirection permanente, appelée aussi 301, pour Hugo,
avec le serveur web nginx… sous OpenBSD ?!</p>
<p>L&rsquo;article de <a href="https://romain.therrat.fr/posts/2020/04/hugo-redirections-301/" rel="external">Romain Therrat</a>
donne les grandes lignes… sauf que sous OpenBSD, ça ne fonctionne pas !</p>
<p>Je reprends les grands principes ci-dessous, adapté à OpenBSD :</p>
<h2 id="configuration">Configuration</h2>
<h3 id="hugo">Hugo</h3>
<p>Le principe est l&rsquo;utilisation des alias d&rsquo;URL.</p>
<p>En partant du principe de l&rsquo;utilisation du format toml, ouvrez le fichier que vous voulez rediriger et dans son entête, ajoutez :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span><span style="color:#06b6ef">aliases</span> = [<span style="color:#ef6155">/</span><span style="color:#06b6ef">ancienne</span><span style="color:#ef6155">/</span><span style="color:#06b6ef">URL</span><span style="color:#ef6155">/</span><span style="color:#06b6ef">de</span><span style="color:#ef6155">/</span><span style="color:#06b6ef">publication</span><span style="color:#ef6155">/</span><span style="color:#06b6ef">fichier</span><span style="color:#ef6155">/</span>]
</span></span></code></pre></div><p><em>Si votre format de fichier de configuration est autre, adaptez !</em></p>
<hr>
<p>Puis modifier le fichier de configuration de Hugo, pour ajouter les directives
suivantes :</p>
<p>⇒ Ajoutez un type de media</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;conf/nginx&#34;</span>]
</span></span></code></pre></div><p>⇒ Ajoutez une sortie à générer, pour la variable <strong>home</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;nginx&#34;</span>, <span style="color:#ef6155">…</span>]
</span></span></code></pre></div><p>⇒ Ajoutez la sortie du format adéquat pour créer le fichier de redirections
pour nginx :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">nginx</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;redirections.conf&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediatype</span> = <span style="color:#48b685">&#34;conf/nginx&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">notAlternative</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">path</span> = <span style="color:#48b685">&#34;nginx-config&#34;</span>
</span></span></code></pre></div><hr>
<p>Puis, créer le <strong>layout</strong> nécessaire : <code>layout/index.nginx</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Nginx redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">{{-  range $p :</span><span style="color:#5bc4bf">=</span> <span style="color:#48b685">site.Pages -}}
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    {{- range .Aliases }}</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rewrite ^{{  . }}$ {{ $p.RelPermalink }} permanent;{{ end }}</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">{{- end }}</span>
</span></span></code></pre></div><hr>
<ul>
<li>Si votre site est monolingue, hugo générera dans le sous-répertoire
<code>nginx-config/redirections.conf</code></li>
<li>Si votre site est multilingues, hugo générera chaque fichier <code>redirections.conf</code>
dans chaque sous-répertoire de langue, tel que <code>fr/nginx-config/redirections.conf</code>.</li>
</ul>
<p>Voilà, toute la configuration Hugo prête à être fonctionnelle !</p>
<h3 id="nginx">nginx</h3>
<p>La configuration présentée ci-dessous est relative à mon site multilingue…
<em>Si le votre est monolingue, adaptez !</em></p>
<hr>
<p>Lorsque vous testerez la configuration, nginx se plaindra, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>nginx: <span style="color:#5bc4bf">[</span>emerg<span style="color:#5bc4bf">]</span> open<span style="color:#5bc4bf">()</span> <span style="color:#48b685">&#34;/var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-conf/redirections.conf&#34;</span> failed <span style="color:#5bc4bf">(</span>2: No such file or directory<span style="color:#5bc4bf">)</span> in /etc/nginx/conf.d/domain.tld.conf:15
</span></span></code></pre></div><p>Et, oui le fichier existe bien, au bon endroit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ls -al /var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-config/redirections.conf
</span></span><span style="display:flex;"><span>-rw-r--r--  <span style="color:#f99b15">1</span> www  www  <span style="color:#f99b15">397</span> Jul <span style="color:#f99b15">28</span> 13:23 /var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-config/redirections.conf
</span></span></code></pre></div><hr>
<p>Copions les fichiers de redirections à la racine du répertoire de configuration
de nginx :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># cp /var/www/htdocs/doc.huc.fr.eu.org/www/en/nginx-config/redirections.conf /etc/nginx/hugo-en-redirections.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># cp /var/www/htdocs/doc.huc.fr.eu.org/www/fr/nginx-config/redirections.conf /etc/nginx/hugo-fr-redirections.conf</span>
</span></span></code></pre></div><p>Puis, avec la directive <strong>include</strong>, incluez ces fichiers de configuration
dans la directive <strong>server</strong> de l&rsquo;hôte virtuel relatif au domaine, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">server</span> <span style="color:#48b685">&#34;domain.tld&#34;</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">include</span> <span style="color:#48b685">/etc/nginx/hugo-en-redirections.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/hugo-fr-redirections.conf</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">location</span> <span style="color:#48b685">/(en|fr)/nginx-conf/redirections.conf</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">deny</span> <span style="color:#48b685">all</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><p>Pour finir, remarquez la directive <strong>location</strong> afin d&rsquo;interdire toute
consultation.</p>
<p>Pensez à vérifier la configuration puis redémarrer le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># nginx -t &amp;&amp; rcctl restart nginx</span>
</span></span></code></pre></div><hr>
<p>Voilà !</p>
<h2 id="documentations">Documentations</h2>
<p>⇒ <a href="https://gohugo.io/content-management/urls/" rel="external">Hugo: URL Management: Aliases</a></p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Configurer Hugo et Nginx sous OpenBSD pour effectuer des redirections permanentes]]></summary>
        <published>2021-07-28T13:50:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:61e2abb8-60f9-7ebe-6758-0e3d34cda9e0</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/pfstat-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: pfstat sur OpenBSD : analyser le flux IPv4 et IPv6 dans PF</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <category term="dataviz" scheme="http://doc.huc.fr.eu.org/fr/tags/dataviz/" />
        <category term="pfstat" scheme="http://doc.huc.fr.eu.org/fr/tags/pfstat/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>pfstat</strong> est un projet de Daniel Hartmeir pour générer des statistiques
graphiques du flux réseau qui passe au-travers du parefeu 







































































<span lang="en">PF <em>(Packet Filter)</em></span>







































.</p>
<ul>
<li>Site web officiel : <a href="https://www.benzedrine.ch/pfstat.html" rel="external">https://www.benzedrine.ch/pfstat.html</a></li>
</ul>
<hr>
<p>⇒ Environnement :</p>
<ul>
<li>OpenBSD : <del>6.9</del> ⇒ 7.1</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Classique : <code># pkg_add pfstat pfstatd</code></p>
<p>Le paquet <strong>pfstatd</strong> n&rsquo;est pas essentiel pour une configuration simple
et minimale. Il devient intéressant pour être fonctionner avec un utilisateur
dédié. ;-)</p>
<h2 id="configuration">Configuration</h2>
<h3 id="pf">PF</h3>
<p>En admettant que l&rsquo;interface réseau est de type <strong>em0</strong>, modifions le fichier
de configuration <code>/etc/pf.conf</code> pour ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">set loginterface em0</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si vous avez plusieurs interfaces réseaux, il est possible de toutes les
analyser ; ligne après ligne, ajoutez chacune d&rsquo;elles, si nécessaire.</div>

<h3 id="pfstat">pfstat</h3>
<p>La configuration de pfstat n&rsquo;est pas compliquée. Pour débuter, le package
installe un fichier de configuration exemple, juste pour IPv4.</p>
<ul>
<li>Fichier de configuration : <code>/etc/pfstat.conf</code></li>
</ul>
<p>Il faut le modifier pour changer le chemin du répertoire de destination
où seront les futures images créées pour la vision et l&rsquo;analyse.</p>
<p>En admettant toujours que l&rsquo;interface reseau à analyser est <strong>em0</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# sed -i -e <span style="color:#48b685">&#39;s/sis0/em0/g;s/benzedrine.cx/pfstat/g&#39;</span> /etc/pfstat.conf
</span></span></code></pre></div><p>La commande va changer toutes les lignes où :</p>
<ul>
<li>l&rsquo;interface <strong>sis0</strong> par <strong>em0</strong></li>
<li>le chemin de publication contenant <em>benzedrine.cx</em> par <em>pfstat</em>.</li>
</ul>
<hr>
<p>Ensuite, il suffit de configurer la crontab de root pour que le binaire
<strong>pfstat</strong> analyse le flux réseau.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">*  * * * * -ns /usr/local/bin/pfstat -q -d /var/db/pfstat/pfstat.db</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">*/15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">30 0 * * * -ns /usr/local/bin/pfstat -t 30 -d /var/db/pfstat/pfstat.db</span>
</span></span></code></pre></div><ul>
<li>la première ligne fonctionne toutes les minutes pour analyser et enregistrer</li>
<li>la seconde ligne a pour propos de générer les images toutes les quinze minutes
depuis la base de données de pfstat</li>
<li>la troisième ligne aura pour propos d&rsquo;effacer toutes les jours à 0:30
les données qui sont vieilles de plus de trente jours.</li>
</ul>
<p>⇒ Cela nécessite la création du répertoire de la future base de données :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /var/db/pfstat/
</span></span></code></pre></div><p><em>Juste pour info, cela peut être absolument un tout autre chemin sur le
système d&rsquo;exploitation, et avoir un tout autre nom de base de données.
C&rsquo;est à vous de voir…</em></p>
<hr>
<p>Voilà une configuration minimale fonctionnelle !</p>
<p>Passons à une configuration plus poussée avec un utilisateur dédié qui
va gérer et le service et l&rsquo;utilisation du binaire.</p>
<h3 id="utilisateur-_pfstat">Utilisateur _pfstat</h3>
<p>L&rsquo;utilisateur dédié nous sera utile pour démarrer le service pfstatd
avec les droits utilisateurs de <strong>_pfstat</strong>, puis d&rsquo;utiliser <strong>pfstat</strong>
avec cet utilisateur…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# useradd -s /sbin/nologin -d /var/db/pfstat _pfstat
</span></span><span style="display:flex;"><span>:# chown _pfstat /var/db/pfstat
</span></span></code></pre></div><h4 id="pfstatd">pfstatd</h4>
<p>Il suffit d&rsquo;activer le service, de le paramétrer et le démarrer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl enable pfstatd
</span></span><span style="display:flex;"><span>:# rcctl set pfstatd flags -u _pfstat -a 127.0.0.1
</span></span><span style="display:flex;"><span>:# rcctl start pfstatd
</span></span></code></pre></div><p>N&rsquo;ayant pas paramétré de numéro de port, c&rsquo;est celui par défaut, à savoir
9999, qui sera écouté.</p>
<p>Des outils comme <strong>nc</strong> peuvent permettre de s&rsquo;assurer du fonctionnement ;
essayez <code>nc localhost 9999</code>, vous devriez avoir les statistiques qui
s&rsquo;affichent rapidement les unes à les suites des autres, ligne après ligne. <br>
<em>Si ce n&rsquo;est pas le cas, il y a un soucis…</em></p>
<h5 id="pfstatd-et-pf">pfstatd et PF</h5>
<p>Je vous encourage vivement à bloquer au niveau du pare-feu d&rsquo;OpenBSD,
toutes tentatives de communications sur le service de pfstatd !</p>
<p>Une règle comme la suivante devrait suffire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">block drop in on ! lo0 proto tcp to port 9999</span>
</span></span></code></pre></div><h4 id="pfstat-et-_pfstat">pfstat et _pfstat</h4>
<p>Maintenant nous allons pouvoir reconfigurer l&rsquo;utilisation de pfstat en
tenant compte de l&rsquo;utilisateur dédié <strong>_pfstat</strong></p>
<ol>
<li>
<p>dans un premier temps, décommentons ou supprimons les écritures dans
la crontab de root,</p>
</li>
<li>
<p>pour paramétrer celle de l&rsquo;utilisateur <strong>_pfstat</strong> :</p>
<ul>
<li>créer un fichier de crontab, tel que <strong>crontab4pfstat</strong>, contenant
les déclarations suivantes :</li>
</ul>
</li>
</ol>
<pre tabindex="0"><code class="language-conf" data-lang="conf">*  * * * * -ns /usr/local/bin/pfstat -q -d /var/db/pfstat/pfstat.db -r 127.0.0.1
*/15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db
30 0 * * * -ns /usr/local/bin/pfstat -t 30 -d /var/db/pfstat/pfstat.db
</code></pre><p>Petites explications :</p>
<ul>
<li>Remarquez l&rsquo;usage de l&rsquo;option <code>-r</code> suivie de l&rsquo;adresse de bouclage
localhost ; cette option nous permet d&rsquo;interroger le service &ldquo;à distance&rdquo;
pour récupèrer les statistiques et les enregistrer dans la base de données.</li>
</ul>
<p>Maintenant injections le fichier <strong>crontab4pfstat</strong> dans la crontab de
l&rsquo;utilisateur <strong>_pfstat</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# crontab -u _pfstat crontab4pfstat
</span></span></code></pre></div><h4 id="surveillance-de-_pfstat">Surveillance de _pfstat</h4>
<p>Il y a différents moyens de surveiller l&rsquo;activité de l&rsquo;utilisateur <strong>_pfstat</strong> :</p>
<ul>
<li><code>top -U _pfstat</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>load averages:  0.05,  0.38,  0.38
</span></span><span style="display:flex;"><span><span style="color:#f99b15">56</span> processes: <span style="color:#f99b15">54</span> idle, <span style="color:#f99b15">2</span> on processor
</span></span><span style="display:flex;"><span>CPU0 states:  0.0% user,  0.0% nice,  0.0% sys,  0.0% spin,  0.0% intr,  100% idle
</span></span><span style="display:flex;"><span>Memory: Real: 84M/5985M act/tot Free: 9778M Cache: 2757M Swap: 0K/32G
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  PID USERNAME PRI NICE  SIZE   RES STATE     WAIT      TIME    CPU COMMAND
</span></span><span style="display:flex;"><span><span style="color:#f99b15">16833</span> _pfstat    <span style="color:#f99b15">2</span>    <span style="color:#f99b15">0</span>  700K  984K sleep/6   netcon    0:00  0.00% pfstatd
</span></span></code></pre></div><hr>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ fstat -u _pfstat -n
</span></span><span style="display:flex;"><span>USER     CMD          PID   FD  DEV      INUM        MODE   R/W    SZ|DV
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>   wd  4,0         <span style="color:#f99b15">2</span>        <span style="color:#f99b15">40755</span>    r      <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>    <span style="color:#f99b15">0</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>    <span style="color:#f99b15">1</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>    <span style="color:#f99b15">2</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>    <span style="color:#f99b15">3</span>  4,0     <span style="color:#f99b15">27028</span>        <span style="color:#f99b15">20600</span>    r   73,0
</span></span><span style="display:flex;"><span>_pfstat  pfstatd    <span style="color:#f99b15">16833</span>    4* internet stream tcp 0x0 127.0.0.1:9999
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ ps aux -U _pfstat
</span></span><span style="display:flex;"><span>USER       PID %CPU %MEM   VSZ   RSS TT  STAT   STARTED       TIME COMMAND
</span></span><span style="display:flex;"><span>_pfstat  <span style="color:#f99b15">16833</span>  0.0  0.0   <span style="color:#f99b15">700</span>   <span style="color:#f99b15">984</span> ??  I       1:19AM    0:00.02 /usr/local/bin/pfstatd -u _pfstat -a 127.0.0.1
</span></span></code></pre></div><p>Ces trois commandes nous confirment que :</p>
<ul>
<li>le service <strong>pfstatd</strong> est démarré avec l&rsquo;utilisateur <strong>_pfstat</strong></li>
<li>le service <strong>pfstatd</strong> écoute bien sur la boucle locale, sur le port 9999
et qu&rsquo;il est en attente de connexion, dans le cas de ces exemples.</li>
</ul>
<hr>
<p>Configurons maintenant httpd !</p>
<h3 id="httpd">httpd</h3>
<p>Commençons par créer le répertoire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /var/www/htdocs/pfstat/
</span></span></code></pre></div><p>Puis occupons-nous du fichier de configuration de httpd <code>/etc/httpd.conf</code>
et ajoutons les déclarations suivantes, au besoin :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">types {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">include &#34;/usr/share/misc/mime.types&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server &#34;pfstat&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on 127.0.0.1 port 80</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/pfstat/&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">directory auto index</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/htdocs/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Il reste à vérifier la configuration et activer/démarrer le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl enable httpd
</span></span><span style="display:flex;"><span>:# httpd -n <span style="color:#5bc4bf">&amp;&amp;</span> rcctl start httpd
</span></span></code></pre></div><p>Il ne reste plus qu&rsquo;à consulter localement, tel que : http://localhost/pfstat</p>
<hr>
<p>Voilà une configuration minimale qui fonctionne et qui restituera des images.</p>
<h4 id="httpd-et-_pfstat">httpd et _pfstat</h4>
<p>Du fait d&rsquo;avoir créé l&rsquo;utilisateur <strong>_pfstat</strong>, donnons à l&rsquo;utilisateur
le droit d&rsquo;écrire dans le répertoire web :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# usermod -G www _pfstat
</span></span><span style="display:flex;"><span>:# chown -R _pfstat:www /var/www/htdocs/pfstat
</span></span></code></pre></div><ul>
<li>ainsi nous intégrons l&rsquo;utilisateur <strong>_pfstat</strong> au groupe web <strong>www</strong></li>
<li>cela nous permet ensuite de pouvoir écrire dans le répertoire web</li>
</ul>
<hr>
<h2 id="pfstats">PFstats</h2>
<p><strong>PFstats</strong> est mon petit projet de page responsive web pour consulter de
manière agréable les images générées par pfstat.</p>
<p>Elle est conçue pour analyser des statistiques d&rsquo;une heure, quotidiennes,
hebdomadaires, et mensuelles, voire annuelles.</p>
<ul>
<li>dépôt : <a href="https://tildegit.org/hucste/pfstats" rel="external">https://tildegit.org/hucste/pfstats</a></li>
<li>N&rsquo;hésitez pas à lire le fichier <a href="https://tildegit.org/hucste/pfstats/src/branch/main/README.md" rel="external">README.md</a></li>
<li>Sous <a href="https://tildegit.org/hucste/pfstats/src/branch/main/LICENSE" rel="external">Licence BSD 2 Clauses</a></li>
</ul>
<p>Voici un aperçu :</p>
<figure>
    <a href="/images/openbsd/pfstats.html.png" title="Aperçu de la page &#39;pfstat.hml&#39;">
    <picture>
        
        <source srcset="/images/openbsd/pfstats.html_hu_24bd26f0d013a58a.webp" type="image/webp">
        
        <img alt="Aperçu de la page &#39;pfstat.hml&#39;" height="204" loading="lazy" src="/images/openbsd/pfstats.html_hu_1f25c63853e61cda.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Aperçu de la page 'pfstat.hml'</figcaption>
</figure>
<hr>
<p>Quelques explications :</p>
<h3 id="pfstatconf">pfstat.conf</h3>
<p>⇒ Le fichier de configuration pfstat.conf est configuré :</p>
<ul>
<li>pour analyser IPv4 et IPv6, au-travers de l&rsquo;interface réseau <strong>em0</strong>,
<em>Modifier l&rsquo;interface par la vôtre</em>.</li>
<li>pour restituer des graphiques d&rsquo;une heure, quotidien, hebdomadaire, et
mensuel.</li>
<li>et pour publier vers le répertoire de publication web <code>/var/www/htdocs/pfstat</code>.</li>
</ul>
<p>Il faut le copier à la place du fichier de configuration original.</p>
<hr>
<p><em>Si vous analysez le fichier correctement, j&rsquo;ai commenté toutes les lignes
concernant le traitement des queues ; en effet quand les lignes sont actives,
pfstat se plaint et s&rsquo;arrête avec le message suivant</em> : <br>
<code>/etc/pfstat.conf:61: ALTQ-style queues not supported anymore</code></p>
<p>Il semble que ce ne soit plus supporté !</p>
<h3 id="pfstathtml">pfstat.html</h3>
<p>Copier les fichiers .css, .js, et .html dans le répertoire de publication web</p>
<h3 id="convert-imgsh">convert-img.sh</h3>
<p>⇒ Ce script shell sert à convertir les images JPEG générées par pfstat
au format avif, et webp.</p>
<p>Il nécessite l&rsquo;installation des paquets <strong>libavif</strong>, et <strong>libwebp</strong>.</p>
<ul>
<li>Ajoutez l&rsquo;utilisateur <strong>_pfstat</strong> au groupe de votre utilisateur, puis</li>
<li>donnez les droits nécessaires sur le script shell</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# usermod -G votre-identifiant-utilisateur _pfstat
</span></span><span style="display:flex;"><span>:# chmod <span style="color:#f99b15">0750</span> /home/votre-identifiant-utilisateur/pfstats/convert-img.sh
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">La génération des images au format AVIF est un peu lente ; ce qui n&rsquo;est
pas le cas des images Webp. Cela dépend aussi de la puissance machine.</div>

<h3 id="pfstats-et-crontab">pfstats et crontab</h3>
<p>Il faudra modifier la deuxième ligne de la crontab de l&rsquo;utilisateur
<strong>_pfstat</strong>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">15 * * * * -ns /usr/local/bin/pfstat -p -d /var/db/pfstat/pfstat.db; /dir/convert-img.sh</span>
</span></span></code></pre></div><p>Ainsi se déroulent les étapes suivantes :</p>
<ul>
<li>la création des images se fait à l&rsquo;heure programmée</li>
<li>le script de conversion d&rsquo;images s&rsquo;exécute</li>
</ul>
<h3 id="pfstats-et-httpd">pfstats et httpd</h3>
<p>Pour gérer correctement les images au format avif et webp, il peut être
nécessaire de modifier légérement la configuration d&rsquo;httpd, pour ajouter
dans le bloc de directives <strong>types</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">image/avif  avif</span>
</span></span></code></pre></div><p>Tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">types {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">include &#34;/usr/share/misc/mime.types&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">image/avif  avif</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>⇒ Pour vérifier le support du format webp :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ grep webp /usr/share/misc/mime.types
</span></span><span style="display:flex;"><span>image/webp                      webp
</span></span></code></pre></div><p>Si la commande n&rsquo;affiche aucun résultat, alors il faudra ajouter au bloc
<strong>types</strong> : <code>image/webp webp</code>.
<em>Depuis OpenBSD 6.9, ce n&rsquo;est pas nécessaire.</em></p>
<h3 id="pfstats-et-nginx">pfstats et nginx</h3>
<p>Si vous êtes plutôt un fan de nginx, lisez mes articles suivants pour
savoir comment gérer :</p>
<ul>
<li>le format avif : 
<a class="inside" href="/fr/web/nginx/nginx-image-avif/" title="Lien interne vers l&#39;article : 'Nginx gère les images au format AVIF'">Nginx gère les images au format AVIF</a>

</li>
<li>le format webp : 
<a class="inside" href="/fr/web/nginx/nginx-image-webp/" title="Lien interne vers l&#39;article : 'Nginx gère les images au format Webp'">Nginx gère les images au format Webp</a>

</li>
</ul>
<p>Il vous suffit d&rsquo;adapter la configuration pour la consultation de la page
web de pfstats.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="altq-style-queues-not-supported-anymore">ALTQ-style queues not supported anymore</h3>
<p>Le message complet est le suivant :
<code>/etc/pfstat.conf:61: ALTQ-style queues not supported anymore</code></p>
<p>Il semble que l&rsquo;analyse des queues ne soit plus possible. Supprimez ou
<strong>commentez</strong> toutes lignes relatives.</p>
<p><em>Dans le fichier de configuration que
je fournis, elles sont commentées, juste au cas où ce serait une erreur
de compréhension ou qu&rsquo;il me manque une information pour les rendre fonctionnelles.</em></p>
<h3 id="dbopen-vardbpfstatpfstatdb-no-such-file-or-directory">dbopen: /var/db/pfstat/pfstat.db: No such file or directory</h3>
<p>Avez-vous bien pensé à créer le répertoire ; vérifiez !</p>
<hr>
<p>Voilà !</p>
<hr>
<h2 id="documentations">Documentations</h2>
<p>⇒ Projet <strong>PFstats</strong> : <a href="https://tildegit.org/hucste/pfstats" rel="external">https://tildegit.org/hucste/pfstats</a></p>
<p>⇒ Qui supportent ces formats :</p>
<ul>
<li><a href="https://caniuse.com/avif" rel="external">https://caniuse.com/avif</a></li>
<li><a href="https://caniuse.com/webp" rel="external">https://caniuse.com/webp</a></li>
</ul>
<hr>
<ul>
<li><a href="https://oldblog.chown.me/blog/faire-des-graphes-a-partir-des-infos-de-pf.html" rel="external">https://oldblog.chown.me/blog/faire-des-graphes-a-partir-des-infos-de-pf.html</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer et utiliser pfstat, pour analyser le flux réseau IPv4 et IPv6 au-travers du parefeu PF, sous OpenBSD !]]></summary>
        <published>2021-07-28T00:13:24+02:00</published>
        <updated>2025-11-11T15:44:28+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4077d964-5b48-8d78-09f2-c181cfc1a080</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/gnome/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Utiliser Gnome</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Gnome" scheme="http://doc.huc.fr.eu.org/fr/tags/gnome/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Gnome</strong> est un des environnements de bureau graphique, disponible aussi sous OpenBSD.</p>
<p>⇒ Environnement :</p>
<ul>
<li>OpenBSD : <del>6.9</del> → 7.1</li>
</ul>
<hr>
<p>Dans ce tutoriel, je pars du principe qu&rsquo;OpenBSD vient d&rsquo;être fraîchement
installé, et que tout est à faire.</p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 les paquets <strong>gnome gnome-extras</strong></p>
<p>L&rsquo;installation de ces paquets installent des dépendances, tels les paquets
<strong>avahi</strong>, <strong>consolekit2</strong>, <strong>dbus</strong>, voire <strong>samba</strong>, <strong>sane-backend</strong>
et bien d&rsquo;autres.</p>
<h2 id="configuration">Configuration</h2>
<p>L&rsquo;environnement Gnome3 fonctionne différement des autres environnements
de bureau. Ne cherchez pas à configurer les fichiers personnels
<strong>.profile</strong>, <strong>.kshrc</strong>, voire <strong>.xsession</strong>, ils ne seront pas pris en
compte pour le démarrage et l&rsquo;utilisation de Gnome.</p>
<h3 id="des-services">Des services</h3>
<p>Si lors de l&rsquo;installation d&rsquo;OpenBSD, vous avez activé <strong>xenodm</strong> - <em>le gestionnaire
d&rsquo;affichage par défaut</em> - désactivez-le !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl disable xenodm</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl stop xenodm</span>
</span></span></code></pre></div><p>Puis on active le gestionnaire de session <strong>gdm</strong> ainsi que tous les services
nécessaires !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable multicast messagebus avahi_daemon gdm</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start multicast messagebus avahi_daemon gdm</span>
</span></span></code></pre></div><h3 id="limites-système">Limites système</h3>
<p>Ainsi que le mentionne le fichier pkg-readme de Gnome, les limites système
par défaut dans OpenBSD ne sont pas assez élevées pour exécuter correctement
Gnome.</p>
<p>Faisons cela bien:</p>
<ul>
<li>Créons une classe de login &ldquo;gnome&rdquo;, et ajoutons notre utilisateur à la classe</li>
</ul>
<p>Pour cela, modifions le fichier <code>/etc/login.conf</code>, en ajoutant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">gnome:\</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">:datasize-cur</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1024M:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">	:tc=default:</span>
</span></span></code></pre></div><hr>
<p>⇒ OpenBSD ≤ 7.0 : de même, pour gdm, qui n&rsquo;aura pas assez de descripteurs de fichiers
à disposition.</p>
<p>créons une classe de login &ldquo;gdm&rdquo;, et ajoutons-la à celle de &ldquo;xenodm&rdquo;.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">gdm:\</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">:tc</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">xenodm:</span>
</span></span></code></pre></div><hr>
<p>Puis modifions notre utilisateur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usermod -L gnome user</span>
</span></span></code></pre></div><p><em>(où &lsquo;user&rsquo; est votre identifiant utilisateur…)</em></p>
<hr>
<p>Voilà !</p>
<p>C&rsquo;est suffisant pour faire fonctionner correctement Gnome sous OpenBSD.
Un petit redémarrage de l&rsquo;OS et ça devrait le faire. :p</p>
<p>Maintenant allons un peu plus loin dans la configuration, tel qu&rsquo;avoir sa
session en langue française, et d&rsquo;autres petites astuces utiles.</p>
<h3 id="langue">Langue</h3>
<p>Pour gérer votre langue - <em>dans mon cas, FR</em> - dès le gestionnaire de session
<strong>gdm</strong>, il faut modifier le fichier <code>/etc/gdm/locale.conf</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: locale.conf,v 1.4 2014/01/08 14:07:48 ajacoutot Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Mimics Linux&#39;s /etc/locale.conf.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See locale(1) for a list of supported locales (`locale -a`).</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># OpenBSD setlocale(3) does not handle LANG</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#LANG=&#34;en_US.UTF-8&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_CTYPE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr_FR.UTF-8&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr_FR.UTF-8&#34;</span>
</span></span></code></pre></div><p>Si vous ne faites pas cette modification, et si vous avez un mot-de-passe
avec des caractères accentués dans votre langue, selon le clavier paramétré
lors de l&rsquo;installation d&rsquo;OpenBSD, vous ne pourrez pas vous connecter, car
gdm utilise par défaut la langue anglaise.</p>
<hr>
<p>Pensez à redémarrer gdm…</p>
<h3 id="gestion-énergie">Gestion Énergie</h3>
<p>Pour la gestion des fonctionnalités de mise en veille et d&rsquo;hibernation,
activez le service <strong>apmd</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable apmd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set apmd flags -A</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start apmd</span>
</span></span></code></pre></div><h3 id="impression">Impression</h3>
<p>Pour gérer l&rsquo;impression, il est utile d&rsquo;installer Cups :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add cups cups-filters cups-libs foomatic-db gutenprint </span>
</span></span></code></pre></div><p>Démarrons les services <strong>cupsd</strong>, voire <strong>cups_browsed</strong> - <em>ce dernier étant
utile pour la détection des imprimantes sur le réseau, utilisant les messages
broadcast de type Bonjour, tel Avahi.</em></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable cupsd cups_browsed</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start cups cups_browsed</span>
</span></span></code></pre></div><p>L&rsquo;administration peut se faire au-travers des paramètres <strong>Imprimantes</strong>,
voire de l&rsquo;interface web de Cups, disponible depuis l&rsquo;URL http://localhost:631,
ou des outils <strong>cupsctl</strong>, <strong>lpadmin</strong>.</p>
<h3 id="libreoffice">LibreOffice</h3>
<p>Le gestionnaire <strong>gnome-documents</strong> ne gère pas, par défaut, le type des
documents Office. Il suffit d&rsquo;installer le paquet <strong>unoconv</strong>.</p>
<h2 id="astuces">Astuces</h2>
<h3 id="clavier">Clavier</h3>
<h4 id="affichage-bureau">Affichage Bureau</h4>
<p>⇒ Ne cherchez pas à masquer toutes les fenêtres pour afficher juste le bureau,
l&rsquo;option n&rsquo;est pas activée par défaut !</p>
<p>Ouvrer l&rsquo;application &ldquo;Paramètres&rdquo; &gt; &ldquo;Raccourcis clavier&rdquo;, puis dans la section
&ldquo;Navigation&rdquo;, chercher &ldquo;Masquer toutes les fenêtres normales&rdquo; qui sera &ldquo;Désactivé&rdquo;.</p>
<p>Cliquez dessus, et paramétrez la combinaison de touches que vous désirez,
tel que les touches &ldquo;Super&rdquo; + &ldquo;D&rdquo; (pour Desktop - <em>Bureau en anglais</em>), ou
&ldquo;Super&rdquo; + &ldquo;B&rdquo;. À vous de voir…</p>
<h3 id="fond-décran-aléatoire">Fond d&rsquo;écran aléatoire</h3>
<p>Cette fonctionnalité n&rsquo;existe pas par défaut !</p>
<p>Je mets à disposition deux scripts pour implémenter cette fonctionnalité.</p>
<p>Retrouvez-les sur mon Git : <a href="https://framagit.org/hucste/tools/tree/master/OpenBSD/Gnome3/WallpaperManager" rel="external">WallpaperManager</a></p>
<p>Lisez les informations pour l&rsquo;installer et l&rsquo;utiliser sans soucis.</p>
<h3 id="pf">PF</h3>
<p>Je n&rsquo;ai pas abordé la question des règles de parefeu, mais voici par exemple :</p>
<p>⇒ Cups :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto tcp from egress:network to egress port 631 flags S/SA modulate state</span>
</span></span></code></pre></div><p>⇒ Avahi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 224.0.0.251 port mdns allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to ff02::fb port mdns allow-opts </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 239.255.255.250 port ssdp allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to { ff02::c, ff05::c, ff08::c } port ssdp allow-opts </span>
</span></span></code></pre></div><p>Bien-sûr, c&rsquo;est à vous de voir à les utiliser, voire à les améliorer selon
vos évidences.</p>
<h2 id="dépannage">Dépannage</h2>
<p><strong>GDM</strong> refuse de démarrer !</p>
<p>Lisez direct le fichier log des démons, voire celui des messages :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># grep gdm /var/log/daemon</span>
</span></span></code></pre></div><h3 id="gdm-couldnt-connect-to-system-bus">Gdm: Couldn&rsquo;t connect to system bus:</h3>
<p>Dans les logs <strong>daemons</strong> ou <strong>messages</strong>, vous avez l&rsquo;équivalent de ce message :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">Jul 23 09:38:14 og3 gdm[56941]: Gdm: Couldn&#39;t connect to system bus: Could not connect: No such file or directory
</code></pre><p>Il est très probable que ce soit parce que le service <strong>messagebus</strong> ne
soit pas activé et démarré.</p>
<p>Avez-vous bien activé tous les services comme écrit en début de cet article ?!</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>les différents fichiers pkg-readme :
<ul>
<li>/usr/local/share/doc/pkg-readmes/gnome</li>
<li>/usr/local/share/doc/pkg-readmes/gnupg</li>
<li>/usr/local/share/doc/pkg-readmes/samba</li>
<li>/usr/local/share/doc/pkg-readmes/sane-backends</li>
<li>et bien d&rsquo;autres…</li>
</ul>
</li>
</ul>
<hr>
<p>Voilà !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer et utiliser l&#39;environnement de bureau graphique Gnome sous OpenBSD !]]></summary>
        <published>2021-07-23T10:49:42+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e02490c7-7eaa-a32d-f4e7-2fb057f4f362</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/xfce4/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Utiliser Xfce4</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Xfce" scheme="http://doc.huc.fr.eu.org/fr/tags/xfce/" />
        <category term="Xfce4" scheme="http://doc.huc.fr.eu.org/fr/tags/xfce4/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Xfce4</strong> est un environnement de bureau graphique, disponible aussi
sous OpenBSD.</p>
<p>⇒ Environnement :</p>
<ul>
<li>OpenBSD : <del>6.6</del> → 7.4</li>
<li>Xfce4 : <del>4.14</del> → 4.18</li>
</ul>
<hr>
<p>Dans ce tutoriel, je pars du principe qu&rsquo;OpenBSD vient d&rsquo;être fraîchement
installé, et que tout est à faire.</p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 les
paquets <code>xfce xfce-extras</code>.</p>
<p>L&rsquo;installation de ces paquets installent des dépendances, tel le paquet
<strong>dbus</strong>.</p>
<h3 id="paquets-supplémentaires">Paquets supplémentaires</h3>
<p>Par défaut, certains paquets liés à l&rsquo;environnement de bureau ne sont
pas installés. À vous de voir si vous voulez le faire !</p>
<ul>
<li><strong>xfce4-icon-theme</strong> : deux, trois packs d&rsquo;icônes supplémentaires</li>
<li><strong>xfce4-power-manager</strong> : gestion de l&rsquo;énergie pour ordinateur portable</li>
<li><strong>xfce4-pulseaudio</strong> : greffon pour le système de son pulseaudio -
<em>mais pulseaudio n&rsquo;est pas nécessaire…</em></li>
<li><strong>xfce4-xkb</strong> : permet la bascule de calques de différentes langues de
clavier - <em>mais est-ce vraiment utile, quand l&rsquo;usage de la commande
<code>setxkbmap</code>, voire tout simplement <code>kbd</code>, suivie du code de langue…
suffit.</em></li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Depuis la version 4.14 d&rsquo;Xfce4, disponible depuis OpenBSD 6.6, il est un
peu plus simple de configurer son environnement système personnel, pour
faire fonctionner aisément Xfce4.</p>
<p>Dans un premier temps, je montre un configuration basique fonctionnel ;
puis, j&rsquo;ajouterai des informations qui peuvent améliorer votre &ldquo;confort&rdquo;
fonctionnel.</p>
<h3 id="xsession">.xsession</h3>
<p>Le premier fichier à créer est le fichier personnel de session
<code>~/.xsession</code> pour y ajouter simplement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">exec xfce4-session</span>
</span></span></code></pre></div><h3 id="profil-utilisateur">profil utilisateur</h3>
<p>Il est impératif d&rsquo;ajouter votre utilisateur système aux deux groupes
systèmes suivants :</p>
<ul>
<li>pour utiliser les fonctions d&rsquo;extinctions et de redémarrage :
<ul>
<li>OpenBSD ≤ 7.3 : <strong>operator</strong></li>
<li>OpenBSD ≥ 7.4 : <strong>_shutdown</strong></li>
</ul>
</li>
<li><strong>wheel</strong> qui autorise à utiliser les fonctions de veille et
d&rsquo;hibernation, si elles sont disponibles sur votre système.</li>
</ul>
<p>Avec des droits administrateurs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usermod -G _shutdown,wheel user</span>
</span></span></code></pre></div><p><em>(modifier &lsquo;user&rsquo; par votre identifiant utilisateur, bien-sûr…)</em></p>
<h3 id="performances">Performances</h3>
<h4 id="apmd">apmd</h4>
<p>Configurer <code><a class="inside" href="/fr/sys/openbsd/apm/" title="Lien interne vers l&#39;article : 'Apm : Programme de contrôle de la gestion de l&#39;énergie et de l&#39;hibernation'">apmd</a>
</code> va nous
permettre d&rsquo;utiliser la veille et l&rsquo;hibernation.
Pour se faciliter, nous le mettrons en mode automatique d&rsquo;ajustement des
performances.</p>
<h4 id="obsdfreqd">obsdfreqd</h4>
<p>Si vous avez un laptop ou que vous souhaitez que le système gère plus
finement l&rsquo;ajustement des performances, vous pouvez préférer
l&rsquo;utilisation d&rsquo;<a class="inside" href="/fr/sys/openbsd/obsdfreqd/" title="Lien interne vers l&#39;article : 'obsdfreqd : un service pour gérer la fréquence CPU / OpenBSD'">obsdfreqd : un service pour gérer la fréquence CPU / OpenBSD</a>.</p>
<p><strong>obsdfreqd</strong> est un gestionnaire de fréquences de CPU, créé par Solène
Rapenne. Il a été officiellement packagé depuis OpenBSD 7.1.</p>
<p>Il remplace le service natif <strong>apmd</strong>.</p>
<hr>
<p>Explications :</p>
<ul>
<li>il est nécessaire de démarrer <strong>apmd</strong> en mode manuel, pour
qu&rsquo;obsdfreqd le gère sans soucis.</li>
<li>les paramètres par défaut d&rsquo;obsdfreqd suffisent généralement.</li>
</ul>
<hr>
<p>Voilà !</p>
<p>C&rsquo;est suffisant pour faire fonctionner correctement Xfce4 sous OpenBSD.
Un petit redémarrage de l&rsquo;OS et ça devrait le faire. :p</p>
<p>Maintenant allons un peu plus loin dans la configuration, tel qu&rsquo;avoir
sa session en langue française, et d&rsquo;autres petites astuces utiles.</p>
<h3 id="profile">.profile</h3>
<p>Commençons par configurer votre fichier personnel de profil <code>~/.profile</code>.</p>
<p>Ajouter à celui de base les mentions suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">EDITOR</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">vi	# ou nano, emacs, voire vim</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ENV</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$HOME/.kshrc</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">fr	# ou fr_FR.UTF8, si vous préférez ; mais ça sera pareil !</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export EDITOR ENV LC_MESSAGES</span>
</span></span></code></pre></div><p>⇒ Explications :</p>
<ul>
<li>Personnellement j&rsquo;aime et utilise l&rsquo;éditeur de texte <strong>nano</strong> ; <code>vi</code>
est installé de base, les autres sont à installer.</li>
<li>Déclaration d&rsquo;un ENVironnement personnalisé, ici l&rsquo;usage du
<strong>Korn Shell</strong>, par défaut, qui est <strong>pdksh</strong>.</li>
<li>Définissons simplement la langue FRançaise - il n&rsquo;y a vraiment pas
besoin de plus.</li>
</ul>
<p>Bien-sûr, nous exportons les trois variables afin qu&rsquo;elles soient toutes
utiles et utilisées ensuite.</p>
<p>Pour finir sur ce sujet, il est bien sûr possible de définir toute
variable d&rsquo;environnement, telle <code>PS1</code> par exemple :</p>
<p><code>export PS1=&quot;[\t] \e[0;35m:\u@\h: \e[0;32m\w \e[0;36m\$ \e[m&quot;</code></p>
<hr>
<p>Voici un exemple du fichier fini :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: dot.profile,v 1.7 2020/01/24 02:09:51 okan Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sh/ksh initialization</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PATH</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export PATH HOME TERM</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EDITOR</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">nano</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ENV</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$HOME/.kshrc</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">fr</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export EDITOR ENV LC_MESSAGES</span>
</span></span></code></pre></div><p>Concernant la variable <strong>ENV</strong>, nous avons déclaré un fichier personnel
<code>~/.kshrc</code>. Par défaut, il n&rsquo;existe pas ; il suffit de le créer avec
votre éditeur de texte favori - <em>ce que nous verrons ci-dessous…</em></p>
<hr>
<p>Il faut modifier votre fichier personnel <code>~/.xsession</code> pour ajouter
l&rsquo;environnement du profil, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">. $HOME/.profile</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">exec xfce4-session</span>
</span></span></code></pre></div><p>Ainsi votre session graphique tiendra compte des différents paramètrages
de votre profil, tel que la gestion de la langue, par exemple…</p>
<h3 id="kshrc">.kshrc</h3>
<p>Le contenu de ce fichier personnel n&rsquo;est pas compliqué. Voici quoi
ajouter pour être fonctionnel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">. /etc/ksh.kshrc</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">. $HOME/.profile</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HISTCONTROL</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">ignoredumps</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HISTFILE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$HOME/.mksh_hist</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HISTSIZE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">10000</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PAGER</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">less</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export PAGER</span>
</span></span></code></pre></div><p>⇒ Explications utiles :</p>
<ul>
<li>On source le fichier d&rsquo;initialisation globale pour ksh <code>/etc/ksh.kshrc</code>
afin d&rsquo;avoir un environnement shell correctement configuré par défaut</li>
<li>On source le fichier de profil personnel et personnalisé</li>
<li>Les variables HIST* sont utiles pour l&rsquo;historique des commandes
effectuées :
<ul>
<li><code>HISTFILE</code> est la variable pour définir le fichier de sauvegarde de
l&rsquo;historique</li>
<li><code>HISTSIZE</code> est le nombre de commande à se souvenir ; à ne pas confondre
avec le nombre de lignes du fichier, qui lui est défini par la
variable <code>HISTFILESIZE</code> -
<em>non définie ici</em>.</li>
<li>Pour finir, il n&rsquo;y a pas besoin d&rsquo;exporter ces variables</li>
</ul>
</li>
</ul>
<h3 id="dbus">dbus</h3>
<p>Le paquet <strong>dbus</strong> est installé en tant que dépendance.</p>
<p>Les modifications ci-dessous ne sont pas essentielles, bien qu&rsquo;utiles.
Elles sont relatées dans le fichier pkg-readme relatif.</p>
<p>Ajouter à votre fichier personnel de session <code>~/.xsession</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">if [ -x /usr/local/bin/dbus-launch -a -z &#34;${DBUS_SESSION_BUS_ADDRESS}&#34; ]; then</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">eval `dbus-launch --sh-syntax --exit-with-x11`</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span></code></pre></div><p>Le fichier ressemblera ainsi au final à cela :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">. $HOME/.profile</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if [ -x /usr/local/bin/dbus-launch -a -z &#34;${DBUS_SESSION_BUS_ADDRESS}&#34; ]; then</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">eval `dbus-launch --sh-syntax --exit-with-x11`</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">exec xfce4-session</span>
</span></span></code></pre></div><hr>
<p>Le pkg-readme <strong>upower</strong> nous informe qu&rsquo;il est utile d&rsquo;exécuter les
services <strong>apmd</strong> et <strong>messagebus</strong> afin que le système de gestion
d&rsquo;énergie fonctionne ; <a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">activons</a>

et <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrons</a>

<strong>messagebus</strong></p>
<p>⇒ À ce propos si votre machine est un ordinateur portable,
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>xfce4-power-manager</code>, qui n&rsquo;est pas fourni par défaut.</p>
<h3 id="impression">Impression</h3>
<p>Pour gérer l&rsquo;impression, il est utile d&rsquo;installer
<a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
.</p>
<p>Démarrons les services <strong>cupsd</strong>, voire <strong>cups_browsed</strong> - <em>ce dernier
étant utile pour la détection des imprimantes sur le réseau, utilisant
les messages broadcast de type Bonjour.</em></p>
<p>Voir : <a class="inside" href="/fr/sys/openbsd/cups/#cups" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
</p>
<p>L&rsquo;administration peut se faire au-travers de l&rsquo;interface web de Cups,
disponible depuis l&rsquo;URL http://localhost:631, ou des outils <strong>cupsctl</strong>,
<strong>lpadmin</strong>.</p>
<hr>
<p>Depuis OpenBSD 6.2, les binaires <strong>lpq</strong>, <strong>lpr</strong>, et <strong>lprm</strong> doivent
être symboliquement liés, pour fonctionner plus facilement.</p>
<p>Éditons à nouveau le fichier personnel <code>~/.kshrc</code> pour y ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">for i in lpq lpr lprm; do alias $i</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">/usr/local/bin/$i; done </span>
</span></span></code></pre></div><h3 id="avahi">Avahi</h3>
<p><strong>Avahi</strong> est sous OpenBSD le service de découverte multicast DNS, de
type Bonjour.</p>
<p>Il suffit d&rsquo;installer le paquet <code><a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">avahi</a>
</code>
pour en profiter puis d&rsquo;activer et démarrer les services dans le bon
ordre.</p>
<h2 id="astuces">Astuces</h2>
<h3 id="pf">PF</h3>
<p>Je n&rsquo;ai pas abordé la question des règles de parefeu, mais voici par
exemple :</p>
<p>⇒ les <a class="inside" href="/fr/sys/openbsd/cups/#r%c3%a8gles-pf" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">règles PF</a>

pour Cups,</p>
<p>⇒ les <a class="inside" href="/fr/sys/openbsd/avahi/#r%c3%a8gles-pf" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">règles PF</a>

pour Avahi.</p>
<p>Bien-sûr, c&rsquo;est à vous de voir à les utiliser, voire à les améliorer
selon vos nécessités.</p>
<h3 id="pour-finir">Pour finir</h3>
<p>Pensez après vos modifications des fichiers personnels, à redémarrer à
minima votre session, voire la machine. À vous de voir ! ;-)</p>
<p>Après, à vous d&rsquo;installer tout autre logiciel qui peut vous être utile.</p>
<hr>
<p>Voilà !</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>les différents fichiers pkg-readme :
<ul>
<li>/usr/local/share/doc/pkg-readmes/xfce</li>
<li>/usr/local/share/doc/pkg-readmes/dbus</li>
<li>/usr/local/share/doc/pkg-readmes/upower</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>la FAQ officielle : <a href="https://wiki.xfce.org/faq" rel="external">https://wiki.xfce.org/faq</a></li>
<li>les trucs et astuces : <a href="https://wiki.xfce.org/tips" rel="external">https://wiki.xfce.org/tips</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer et utiliser l&#39;environnement de bureau graphique Xfce4 sous OpenBSD !]]></summary>
        <published>2021-07-20T21:05:54+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:32df3fba-ff30-6979-fc60-60f623b95456</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/nut/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Gérer un onduleur avec NUT</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="NUT" scheme="http://doc.huc.fr.eu.org/fr/tags/nut/" />
        <category term="UPS" scheme="http://doc.huc.fr.eu.org/fr/tags/ups/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ayant un onduleur Eaton Ellipse ECO, j&rsquo;utilise le projet <abbr title="Network UPS Tools">NUT</abbr>
pour le gérer sous OpenBSD.</p>
<p>⇒ Environnement :</p>
<ul>
<li>OpenBSD : <del>6.9</del> ⇒ 7.6</li>
</ul>
<p>⇒ Matériel UPS : <del>Eaton Ellipse ECO 650 VA USB FR</del>, <strong>MGE ELLIPSE 1000</strong></p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 <strong>nut</strong></p>
<h2 id="configuration">Configuration</h2>
<p>Le binaire <strong>nut-scanner</strong> permet de détecter tout matériel UPS connecté,
que ce soit par USB, ou réseau.</p>
<p>Avec des droits admins :</p>
<ul>
<li>Exemple pour le Eaton Ellipse ECO 650 VA USB FR :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas nut-scanner
</span></span><span style="display:flex;"><span>SNMP library not found. SNMP search disabled.
</span></span><span style="display:flex;"><span>Neon library not found. XML search disabled.
</span></span><span style="display:flex;"><span>AVAHI client library not found. AVAHI search disabled.
</span></span><span style="display:flex;"><span>Scanning USB bus.
</span></span><span style="display:flex;"><span>No start IP, skipping NUT bus <span style="color:#5bc4bf">(</span>old connect method<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>nutdev1<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">driver</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;usbhid-ups&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;auto&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">vendorid</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;0463&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">productid</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;FFFF&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">product</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;Ellipse ECO&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">serial</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;000000000&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">vendor</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;EATON&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">bus</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;005&#34;</span>
</span></span></code></pre></div><ul>
<li>Exemple avec le MGE ELLIPSE 1000 :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Cannot load SNMP library <span style="color:#5bc4bf">(</span>libnetsnmp.so<span style="color:#5bc4bf">)</span> : file not found. SNMP search disabled.
</span></span><span style="display:flex;"><span>Cannot load XML library <span style="color:#5bc4bf">(</span>libneon.so<span style="color:#5bc4bf">)</span> : file not found. XML search disabled.
</span></span><span style="display:flex;"><span>Scanning USB bus.
</span></span><span style="display:flex;"><span>No start IP, skipping NUT bus <span style="color:#5bc4bf">(</span>old connect method<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Scanning NUT bus <span style="color:#5bc4bf">(</span>avahi method<span style="color:#5bc4bf">)</span>.
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>nutdev1<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">driver</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;usbhid-ups&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;auto&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">vendorid</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;0463&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">productid</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;FFFF&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">product</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;ELLIPSE&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">serial</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;1H6G4401F&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">vendor</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;MGE UPS SYSTEMS&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">bus</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;001&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">device</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;002&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">busport</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;002&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">###NOTMATCHED-YET###bcdDevice = &#34;4241&#34;</span>
</span></span></code></pre></div><p>Ensuite, plusieurs fichiers de configurations sont à modifier. Tout changement
dans un des fichiers de configuration nécessite le redémarre des services
ad hoc.</p>
<h3 id="upsconf">ups.conf</h3>
<p>Il faut remplir le fichier de configuration <code>/etc/nut/ups.conf</code> avec les
informations retournées par le logiciel.</p>
<ul>
<li>Exemple pour le Eaton Ellipse ECO 650 VA USB FR :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[eaton]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">desc</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;Eaton Ellipse ECO 650 VA USB FR&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    driver = &#34;usbhid-ups&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    port = &#34;auto&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    vendorid = &#34;0463&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    productid = &#34;FFFF&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    product = &#34;Ellipse ECO&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    serial = &#34;000000000&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    vendor = &#34;EATON&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    bus = &#34;005&#34;</span>
</span></span></code></pre></div><h3 id="upsdconf">upsd.conf</h3>
<p>Ce fichier de configuration permet de paramètrer le contrôle de l&rsquo;accès
aux données gérées par le serveur upsd. Par défaut, le service est seulement
accessible sur localhost, en IPv4 et IPv6, sur le port 3493.</p>
<p>C&rsquo;est ce fichier de configuration qu&rsquo;il faudra modifier pour utiliser
l&rsquo;encapsulation TLS, si besoin.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Depuis la version 2.4.0 du projet NUT, les directives <strong>ACL</strong> et <strong>allowfrom</strong>
ont été remplacés par la directive <strong>LISTEN</strong> et le mécanisme tcp-wrappers.
<em>(cf la <a href="https://networkupstools.org/docs/user-manual.chunked/apis12.html" rel="external">note de changements</a>…)</em></p>
<p>Ne cherchez plus à utiliser les directives ACL ; beaucoup de vieux tutoriels
y font de fait références. Tenez en compte !</p>
</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si la directive LISTEN est modifiée/configurée pour permettre l&rsquo;écoute sur
une adresse IPv4, IPv6, il sera nécessaire de configurer le parefeu PF
pour autoriser la connexion sur le port adéquat, et filtrer ainsi les requêtes.</div>

<h3 id="upsdusers">upsd.users</h3>
<p>Ce fichier de configuration permet de configurer des utilisateurs qui auront
les droits d&rsquo;interagir avec le serveur upsd.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est IMPératif que ce fichier ait des droits systèmes les plus minimalistes !
<em>Par défaut, sous OpenBSD, seul l&rsquo;utilisateur dédié y a accès en lecture-écriture.</em></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas chmod <span style="color:#f99b15">0400</span> /etc/nut/upsd.users
</span></span></code></pre></div></div>

<p>Profitons en pour configurer un utilisateur qui aura le droit de communiquer
entre les services upsd et upsmon.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[upsmon]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">password</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">***
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    upsmon master</span>
</span></span></code></pre></div><p>Ainsi nous créons :</p>
<ul>
<li>un utilisateur nommé <strong>upsmon</strong> - <em>vous pouvez très bien choisir tout autre
caractère ; à vous de le réutiliser correctement ensuite</em>…</li>
<li>qui a des droits maître sur le service upsmon.
<ul>
<li><em>(la connotation n&rsquo;a rien à voire avec de l&rsquo;esclavage, elle définit
le rôle qui selon sa dominance arrêtera en premier ou dernier le système,
dans le cas de gestion des plusieurs OS connectés ; dans le contexte
d&rsquo;un seul OS géré, la valeur <strong>master</strong> s&rsquo;impose d&rsquo;elle-même)</em>.</li>
</ul>
</li>
<li>ensuite, modifier la valeur de la directive <strong>password</strong> par celle de votre choix.</li>
</ul>
<p>Puis modifions le fichier <strong>upsmon.conf</strong>.</p>
<h3 id="upsmonconf">upsmon.conf</h3>
<p>Ce fichier de configuration paramètre le service moniteur.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention ce fichier renferme des informations sensibles, il est donc
impératif de veiller aux permissions et droits utilisateur.</div>

<p>Suite à la modification du fichier <strong>upsd.users</strong> pour configurer un utilisateur
<strong>upsmon</strong>, il nous faut ajouter une directive <strong>MONITOR</strong>, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">MONITOR eaton@localhost 1 upsmon *** master</span>
</span></span></code></pre></div><p><em>(Les &lsquo;***&rsquo; doivent correspondre au mot de passe configuré dans le
fichier <strong>upsd.users</strong> pour l&rsquo;utilisateur <strong>upsmon</strong>)</em>.</p>
<p>Ensuite, il faut modifier à minima, les directives <strong>NOTIFYMSG</strong>, <strong>NOTIFYFLAG</strong> ;
je vous renvoie à la documentation officielle, ainsi que pour connaître
le rôle des autres directives.</p>
<p>Concernant les directives <strong>NOTIFYFLAG</strong>, il importe d&rsquo;ajouter le drapeau <strong>EXEC</strong>
pour l&rsquo;exécution des commandes liées. Sans, celles-ci ne seront pas exécutées.</p>
<p>Finissons par parler de la directive <strong>NOTIFYCMD</strong> qui n&rsquo;est pas paramétrée
correctement :</p>
<ul>
<li>dans un premier temps, décommentons-la, puis</li>
<li>changeons le chemin vers le binaire <strong>upssched</strong></li>
</ul>
<p>Tel que :</p>
<p><code>NOTIFYCMD /usr/local/sbin/upssched</code></p>
<p>Ainsi le service <strong>upsmon</strong> passera le relais au binaire <strong>upssched</strong>,
qui lira alors la configuration du fichier <strong>upssched.conf</strong>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pourquoi faire cela ?</p>
<p>C&rsquo;est simplement recommandé par la doc officielle, dans la sous section
<strong><a href="https://networkupstools.org/docs/user-manual.chunked/ar01s07.html" rel="external">Suppressing notify storms</a></strong>
où il est clairement écrit d&rsquo;utiliser <strong>upssched</strong> en tant que
notificateur de commande, afin d&rsquo;éviter une &ldquo;tornade de notifications&rdquo;,
qui pourrait avoir lieu dans certains contextes, si la directive <strong>NOTIFYCMD</strong>
n&rsquo;était pas configurée.</p>
</div>

<h3 id="upsschedconf">upssched.conf</h3>
<p>Ce fichier de configuration permet de configurer des actions à planifier.</p>
<p>Il faut décommenter les directives <strong>PIPEFN</strong>, <strong>LOCKFN</strong>, et enfin les
directives <strong>AT</strong>.</p>
<p>Concernant les deux directives <strong>LOCKFN</strong> et <strong>PIPEFN</strong>, le chemin absolu
renseigné par défaut n&rsquo;existe pas ; il faut le créer et lui donner les droits
de l&rsquo;utilisateur <strong>_ups</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# install -d -o _ups -g wheel -m <span style="color:#f99b15">750</span> /var/db/nut/upssched
</span></span></code></pre></div><p>Ensuite créer les directives <strong>AT</strong> nécessaires ; voici ce que j&rsquo;ai configuré :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AT ONBATT * START-TIMER onbatt 15</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AT ONBATT * START-TIMER onbattwarn 30</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AT ONLINE * CANCEL-TIMER onbatt</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AT ONLINE * CANCEL-TIMER onbattwarn</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AT ONLINE * EXECUTE ups-back-on-line</span>
</span></span></code></pre></div><p>Sans parler qu&rsquo;il est possible de modifier le script <code>/usr/local/bin/upssched-cmd</code>,
pour interagir avec le système selon l&rsquo;événement appelé.</p>
<p>Veuillez lire plus profondément la doc officielle.</p>
<h3 id="upssetconf">upsset.conf</h3>
<p>Ce fichier de configuration permet l&rsquo;usage de scripts CGI, fournit dans le
paquet <strong>nut-cgi</strong> et n&rsquo;a qu&rsquo;un rôle : celui d&rsquo;attester que la configuration
pour utiliser les scripts CGI en question est bel et bien (soit-disant ?)
sécurisée.</p>
<p>Il ne sert <strong>que</strong> dans ce contexte.</p>
<h3 id="permissions">Permissions</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">À chaque migration de version d&rsquo;OpenBSD, il sera nécessaire de changer à
nouveau les permissions, car elles sont réinitialisées par défaut.</div>

<p>Sous OpenBSD, lors de l&rsquo;installation du binaire, sont configurés :</p>
<ul>
<li>un utilisateur : <strong>_ups</strong></li>
<li>le groupe : <strong>_ups</strong></li>
</ul>
<p>Il est nécessaire de configurer les permissions utilisateurs afin d&rsquo;avoir
accès au nœud de dispositif adéquat.</p>
<p>⇒ Pour les dispositifs USB, il faut identifier le contrôleur USB sur lequel
est connecté le périphérique UPS, voire le(s) nœud(s) de dispositifs <strong>ugen</strong>.</p>
<p>Utilisons la commande <strong>usbdevs</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas usbdevs
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Controller /dev/usb5:
</span></span><span style="display:flex;"><span>addr 01: 1002:0000 ATI, OHCI root hub
</span></span><span style="display:flex;"><span>addr 02: 0463:ffff EATON, Ellipse ECO
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p><em>Dans mon cas, le périphérique UPS est connecté sur le contrôleur <strong>usb5</strong>,
sans nœud de dispositifs précisé</em>.</p>
<p>Ensuite, il suffit de changer les droits utilisateurs sur le dispositif adéquat ;
dans mon cas :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas chown :_ups /dev/usb5 <span style="color:#776e71"># ou, chgrp _ups /dev/usb5</span>
</span></span><span style="display:flex;"><span>:$ doas chmod g+w /dev/usb5
</span></span></code></pre></div><p>Ainsi le groupe <strong>_ups</strong> a accès au contrôleur !</p>
<p>Pour finir, assurons-nous d&rsquo;avoir les droits utilisateurs sur les fichiers du
répertoire de configuration &lsquo;/etc/nut&rsquo; :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas chown _ups:_ups /etc/nut/ups*
</span></span></code></pre></div><p>Normalement, cela suffit pour démarrer les services adéquats.</p>
<hr>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Certains onduleurs de type APC USB ont des soucis, veuillez vous réferer au
fichier pkg-readme fourni !</div>

<hr>
<p>⇒ Si l&rsquo;onduleur est connecté par le port RS232, il faut soit :</p>
<ul>
<li>ajouter l&rsquo;utilisateur <strong>_ups</strong> au groupe <strong>dialer</strong>,</li>
<li>modifier les droits utilisateur sur le dispositif <code>/dev/tty</code> adéquat pour
que l&rsquo;utilisateur <strong>_ups</strong> puisse le gérer.</li>
</ul>
<p><em>Ce n&rsquo;est pas le cas de mon onduleur !</em> ;-)</p>
<h3 id="services">Services</h3>
<p>Côté service, il faut donc activer puis démarrer les démons suivants :</p>
<ul>
<li><strong>upsd</strong> : le service qui gère le serveur réseau</li>
<li><strong>upsmon</strong> : le service qui gère le moniteur</li>
</ul>
<p>Le service <strong>upsd</strong> doit être démarré avant le service <strong>upsmon</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas rcctl enable upsd upsmon
</span></span><span style="display:flex;"><span>:$ doas rcctl set upsd flags -u _ups
</span></span><span style="display:flex;"><span>:$ doas rcctl start upsd upsmon
</span></span></code></pre></div><p>Normallement, le log <strong>daemon</strong> doit notifier ainsi les services :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 usbhid-ups<span style="color:#5bc4bf">[</span>47317<span style="color:#5bc4bf">]</span>: Startup successful
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 upsd<span style="color:#5bc4bf">[</span>83153<span style="color:#5bc4bf">]</span>: listening on ::1 port <span style="color:#f99b15">3493</span>
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 upsd<span style="color:#5bc4bf">[</span>83153<span style="color:#5bc4bf">]</span>: listening on 127.0.0.1 port <span style="color:#f99b15">3493</span>
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 upsd<span style="color:#5bc4bf">[</span>83153<span style="color:#5bc4bf">]</span>: Connected to UPS <span style="color:#5bc4bf">[</span>eaton<span style="color:#5bc4bf">]</span>: usbhid-ups-eaton
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 upsd<span style="color:#5bc4bf">[</span>90348<span style="color:#5bc4bf">]</span>: Startup successful
</span></span><span style="display:flex;"><span>Jul <span style="color:#f99b15">17</span> 13:25:34 sh1 upsmon<span style="color:#5bc4bf">[</span>19005<span style="color:#5bc4bf">]</span>: Startup successful
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h2 id="vérification">Vérification</h2>
<h3 id="état">État</h3>
<p>Le binaire <strong>upsc</strong> permet de vérifier l&rsquo;état de l&rsquo;onduleur, tel que :</p>
<p><code>:$ upsc eaton</code> est la même chose que faire <code>:$ upsc eaton@localhost</code></p>
<p>⇒ Connaître l&rsquo;état de la batterie :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ upsc eaton ups.status
</span></span><span style="display:flex;"><span>OL
</span></span></code></pre></div><ul>
<li>La réponse <strong>OL</strong> signifie que la batterie fonctionne bien et que l&rsquo;UPS est bien en ligne électrique ; <strong>OL</strong> : <strong>On Line</strong>
<ul>
<li><strong>OB</strong> : <strong>On Battery</strong>  signifie que l&rsquo;onduleur ne fonctionne plus que sur la batterie</li>
<li><strong>LB</strong> : <strong>Low Battery</strong> signifie que la batterie est à son niveau de charge le plus bas</li>
</ul>
</li>
</ul>
<p>Les indicateurs <strong>OB</strong> et <strong>LB</strong> doivent déclencher des actions selon ce
qui est paramétré dans les fichiers de configuration <strong>upsmon.conf</strong>, voire
<strong>upssched.conf</strong>.</p>
<h3 id="processus-et-fichiers-ouverts">Processus et fichiers ouverts</h3>
<p>Il est possible de vérifier quels processus sont gérés par l&rsquo;utilisateur <strong>_ups</strong>,
voire quels sont les fichiers ouverts par lui, par exemple avec les
commandes <code>ps</code> et <code>fstat</code>, tels que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ps aux -U _ups
</span></span><span style="display:flex;"><span>USER       PID %CPU %MEM   VSZ   RSS TT  STAT   STARTED       TIME COMMAND
</span></span><span style="display:flex;"><span>_ups     <span style="color:#f99b15">31655</span>  0.0  0.0   <span style="color:#f99b15">836</span>  <span style="color:#f99b15">1668</span> ??  S       5:07PM    0:00.70 /usr/local/bin/usbhid-ups -a eaton
</span></span><span style="display:flex;"><span>_ups      <span style="color:#f99b15">4840</span>  0.0  0.0   <span style="color:#f99b15">764</span>  <span style="color:#f99b15">1308</span> ??  S       5:07PM    0:00.12 /usr/local/sbin/upsd -u _ups
</span></span><span style="display:flex;"><span>_ups     <span style="color:#f99b15">65469</span>  0.0  0.0   <span style="color:#f99b15">780</span>  <span style="color:#f99b15">3084</span> ??  S       5:07PM    0:00.09 /usr/local/sbin/upsmon
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ fstat -u _ups -n
</span></span><span style="display:flex;"><span>USER     CMD          PID   FD  DEV      INUM        MODE   R/W    SZ|DV
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>   wd  4,0    <span style="color:#f99b15">103712</span>        <span style="color:#f99b15">40700</span>    r      <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>    <span style="color:#f99b15">0</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>    <span style="color:#f99b15">1</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>    <span style="color:#f99b15">2</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>    3* internet stream tcp 0x0 127.0.0.1:26706 --&gt; 127.0.0.1:3493
</span></span><span style="display:flex;"><span>_ups     upsmon     <span style="color:#f99b15">65469</span>    <span style="color:#f99b15">4</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>   wd  4,4     <span style="color:#f99b15">26111</span>        <span style="color:#f99b15">40700</span>    r      <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    <span style="color:#f99b15">0</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    <span style="color:#f99b15">1</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    <span style="color:#f99b15">2</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    3* internet6 stream tcp 0x0 <span style="color:#5bc4bf">[</span>::1<span style="color:#5bc4bf">]</span>:3493
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    4* internet stream tcp 0x0 127.0.0.1:3493
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    5* unix stream 0x0
</span></span><span style="display:flex;"><span>_ups     upsd        <span style="color:#f99b15">4840</span>    6* internet stream tcp 0x0 127.0.0.1:3493 &lt;-- 127.0.0.1:26706
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>   wd  4,4     <span style="color:#f99b15">26111</span>        <span style="color:#f99b15">40700</span>    r      <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    <span style="color:#f99b15">0</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    <span style="color:#f99b15">1</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    <span style="color:#f99b15">2</span>  4,0     <span style="color:#f99b15">27162</span>        <span style="color:#f99b15">20666</span>   rw    2,2
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    <span style="color:#f99b15">3</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    <span style="color:#f99b15">4</span> pipe 0x0 state:
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    5* unix stream 0x0 /var/db/nut/usbhid-ups-eaton
</span></span><span style="display:flex;"><span>_ups     usbhid-ups <span style="color:#f99b15">31655</span>    6* unix stream 0x0 /var/db/nut/usbhid-ups-eaton
</span></span></code></pre></div><p>Ainsi, on remarque que :</p>
<ul>
<li>les services upsd et upsmon fonctionnent, bien gérés par l&rsquo;utilisateur <strong>_ups</strong>
<ul>
<li>des flux TCP sont bien créés, utilisés sur localhost</li>
</ul>
</li>
<li>que le binaire <strong>usbhid-ups</strong> correspondant à celui qui prend en charge
l&rsquo;UPS fonctionne bien sur le profil <strong>eaton</strong> créé</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="connection-refused">Connection refused</h3>
<p>Voici, la série de messages :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>upsd<span style="color:#5bc4bf">[</span>55984<span style="color:#5bc4bf">]</span>: Can<span style="color:#ef6155">&#39;</span>t connect to UPS <span style="color:#5bc4bf">[</span>eaton<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>usbhid-ups-eaton<span style="color:#5bc4bf">)</span>: Connection refused
</span></span><span style="display:flex;"><span>upsmon<span style="color:#5bc4bf">[</span>20574<span style="color:#5bc4bf">]</span>: Poll UPS <span style="color:#5bc4bf">[</span>eaton@localhost<span style="color:#5bc4bf">]</span> failed - Driver not connected
</span></span><span style="display:flex;"><span>upsmon<span style="color:#5bc4bf">[</span>20574<span style="color:#5bc4bf">]</span>: Communications with UPS eaton@localhost lost
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>upsmon<span style="color:#5bc4bf">[</span>44238<span style="color:#5bc4bf">]</span>: UPS eaton@localhost is unavailable
</span></span><span style="display:flex;"><span>upsmon<span style="color:#5bc4bf">[</span>44238<span style="color:#5bc4bf">]</span>: UPS <span style="color:#5bc4bf">[</span>eaton@localhost<span style="color:#5bc4bf">]</span>: connect failed: Connection failure: Connection refused
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Au minimum, deux raisons possibles :</p>
<ul>
<li>
<p><strong>vérifiez la connexion physique USB</strong> de l&rsquo;onduleur. Il peut être utile
de changer de câble USB, et/ou de débrancher pour rebrancher le câble.
De même les ports USB de votre carte-mère, ou de votre hub USB commencent
peut-être à être défectueux.</p>
</li>
<li>
<p><strong>lors d&rsquo;une migration d&rsquo;OpenBSD</strong> : il faut refaire les
<a href="/fr/sys/openbsd/nut/#permissions">permissions</a> nécessaires !</p>
</li>
</ul>
<h3 id="login-failed">Login failed</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>upsmon<span style="color:#5bc4bf">[</span>39287<span style="color:#5bc4bf">]</span>: Login on UPS <span style="color:#5bc4bf">[</span>eaton@localhost<span style="color:#5bc4bf">]</span> failed - got <span style="color:#5bc4bf">[</span>ERR ACCESS-DENIED<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><p>Vérifier qu&rsquo;un utilisateur a été configuré dans les fichiers <strong>upsd.users</strong>,
qu&rsquo;il corresponde bien à celui paramétré dans <strong>upsmon.conf</strong>.</p>
<h3 id="permission-denied">Permission denied</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>upsd<span style="color:#5bc4bf">[</span>87303<span style="color:#5bc4bf">]</span>: Can<span style="color:#ef6155">&#39;</span>t open /etc/nut/upsd.conf: Permission denied
</span></span></code></pre></div><p>Vérifier les droits utilisateurs sur le fichier en question, il doit appartenir
à l&rsquo;utilisateur <strong>_ups</strong></p>
<hr>
<h2 id="nut-cgi">nut-cgi</h2>
<p>Le binaire <strong>nut-cgi</strong> fournit des scripts CGI pour interagir/visionner
au-travers d&rsquo;un service web le fonctionnement de l&rsquo;onduleur.</p>
<p>Dans les faits, cela ne fonctionne officiellement qu&rsquo;avec le serveur Apache,
et nécessite l&rsquo;écriture d&rsquo;un fichier de configuration <strong>hosts.conf</strong>, non créé par défaut.</p>
<hr>
<p>Pour la petite histoire, j&rsquo;ai essayé de paramétrer et utiliser les services
natifs que sont <strong>httpd</strong> et <strong>slowcgi</strong> puis à modifier le fichier de configuration
<strong>upsset.conf</strong>, mais le service refuse de fonctionner en informant qu&rsquo;il
s&rsquo;arrête par défaut de sécurité.</p>
<p>Résultat : <strong>nut-cgi</strong> semble ne pas fonctionner avec <strong>httpd</strong>…</p>
<p>Voici ci-dessous la configuration testée :</p>
<h3 id="httpd">httpd</h3>
<p>Ici la configuration minimaliste du serveur httpd utilisée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">types {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">include &#34;/usr/share/misc/mime.types&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server &#34;default&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on 127.0.0.1 port 80</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">log { access &#34;httpd-default-access.log&#34;, error &#34;httpd-default-error.log&#34; }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/cgi-bin/nut/upsset.cgi&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">fastcgi socket &#34;/run/slowcgi.sock&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><h3 id="bin-sh">bin sh</h3>
<p>Pour que les scripts CGI, il semble nécessaire d&rsquo;installer le binaire <strong>sh</strong>
dans le chroot web :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas install -o root -g bin -m <span style="color:#f99b15">0555</span> /bin/sh /var/www/bin/
</span></span></code></pre></div><h3 id="utilisateur-www">utilisateur www</h3>
<p>Il faut aussi donner les droits de l&rsquo;utilsateur <strong>www</strong> sur le scrit CGI,
tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas chown www:bin /var/www/cgi-bin/nut/upsset.cgi
</span></span></code></pre></div><p>Il est de même possible de faire de même pour les deux autres scripts CGI ;
à ne faire que si vraiment le besoin est réel.</p>
<h3 id="nut-cgi-et-hostsconf">nut-cgi et hosts.conf</h3>
<p>Le fichier de configuration <strong>hosts.conf</strong> n&rsquo;existe pas par défaut, sous OpenBSD.
Il faut le créer et lui donner les droits de l&rsquo;utilisateur <strong>_ups</strong>.</p>
<p>Dans mon cas :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ doas echo <span style="color:#48b685">&#34;MONITOR eaton@localhost \&#34;Eaton Ellipse ECO 650 VA USB FR\&#34;&#34;</span> &gt; /etc/nut/hosts.conf
</span></span><span style="display:flex;"><span>:$ doas chown _ups:_ups /etc/nut/hosts.conf
</span></span></code></pre></div><h3 id="nut-cgi-et-upssetconf">nut-cgi et upsset.conf</h3>
<p>Il est nécessaire de décommenter l&rsquo;écriture <strong>I_HAVE_SECURED_MY_CGI_DIRECTORY</strong>
dans le fichier de configuration <strong>upsset.conf</strong></p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li>Projet NUT : <a href="https://networkupstools.org/" rel="external">https://networkupstools.org/</a></li>
<li>pkg-readme : <code>/usr/local/share/doc/pkg-readmes/nut</code></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer un onduleur avec le projet NUT sur OpenBSD]]></summary>
        <published>2021-07-18T15:34:24+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1efe3dc1-2b3f-8d26-c8b6-89c0b21b4843</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-howto-dl/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Comment télécharger en ligne de commande sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par défaut, il y a la commande <code>ftp</code> utile pour télécharger un fichier en http :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ftp -o /chemin/vers/lefichier.zip http://URL.com/fichier
</span></span></code></pre></div><hr>
<p><strong>Il n&rsquo;y a ni <code>wget</code> ni <code>curl</code> par défaut !</strong></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour savoir comment télécharger en mode CLI depuis OpenBSD]]></summary>
        <published>2021-05-25T16:16:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4d63b2ec-8ecd-4238-87fd-691d94db7154</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-checksum/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Créer une somme de contrôle sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="checksum" scheme="http://doc.huc.fr.eu.org/fr/tags/checksum/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Historiquement, sous OpenBSD, on utilise l&rsquo;outil natif
<a href="https://man.openbsd.org/cksum" rel="external"><code>cksum</code>(1)</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cksum -a <span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span> -h <span style="color:#f99b15">${</span><span style="color:#ef6155">hashfile</span><span style="color:#f99b15">}</span> nom_fichier
</span></span></code></pre></div><ul>
<li><code>algo</code> : est le nom de l&rsquo;algorithme à choisir, parmi <code>cksum</code>, <code>md5</code>,
<code>rmd160</code>, <code>sha1</code>, <code>sha224</code>, <code>sha256</code>, <code>sha384</code>, <code>sha512/256</code>, et
<code>sha512</code></li>
<li><code>hashfile</code> : est le fichier de sorti de la somme de contrôle calculée</li>
</ul>
<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Note: il est aussi possible d&rsquo;utiliser directement les algorithmes, tel que :
<code>$ sha256 -h ${hashfile} nom_fichier</code></div>

<hr>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Ainsi que le rappelle le manpage <a href="https://man.openbsd.org/md5.1" rel="external"><code>md5</code>(1)</a> :
Il n&rsquo;est pas recommandé d&rsquo;utiliser les algorithmes MD5, SHA1.</div>

<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        
        <published>2021-05-25T16:03:18+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:18be315d-e310-48ba-0f52-7e079bf0575f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-video/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gérer la vidéo sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Video" scheme="http://doc.huc.fr.eu.org/fr/tags/video/" />
        <content type="html"><![CDATA[<h2 id="enregistrement-vidéo">Enregistrement Vidéo</h2>
<p>Par défaut, depuis OpenBSD 6.9, pour des raisons de confidentialité,
l&rsquo;enregistrement vidéo est désactivé !</p>
<p>Pour le réactiver : <code># sysctl kern.video.record=1</code></p>
<p>N&rsquo;oubliez pas de modifier le fichier <code>/etc/sysctl.conf</code> en conséquence,
si vous désirez qu&rsquo;il soit actif dès le démarrage :</p>
<p><code># echo kern.video.record=1 &gt;&gt; /etc/sysctl.conf</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour gérer la vidéo sous OpenBSD]]></summary>
        <published>2021-05-15T12:48:12+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:88c8a4bc-882b-5042-bbe4-17af688b1f70</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/solene-rapenne/openbsd-bases-services/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Liste complète des services offerts par défaut dans OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Services" scheme="http://doc.huc.fr.eu.org/fr/tags/services/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="https://dataswamp.org/~solene/2021-02-16-openbsd-base-services.html" rel="external">Full list of services offered by a default OpenBSD installation</a></strong>&rdquo;,
écrit par Solène Rapenne.</p>
<hr>
<h2 id="introduction">Introduction</h2>
<p>Cet article donne une courte description de CHACUN des services disponibles
dans l&rsquo;installation par défaut d&rsquo;OpenBSD (






<span lang="fr">càd <em>(c&#39;est-à-dire)</em></span>








































































































 hors packages
installés).</p>
<p>Parmi tous dans cette liste, les services suivant sont démarrés par défaut :
cron, pflogd, sndiod, openssh, ntpd, syslogd et smtpd. Les démons réseaux
que sont smtpd (localement), openssh et ntpd (client), sont fonctionnels.</p>
<h2 id="liste-des-services">Liste des Services</h2>
<p>J&rsquo;ai extrait cette liste des services installés dans la base en recherchant
dans <code>/etc/rc/conf</code>.</p>
<p><code>:$ grep _flags /etc/rc.conf | cut -d '_' -f 1</code></p>
<h3 id="amd">amd</h3>
<p>Ce démon est utilisé pour monter automatiquement un serveur 
































































<span lang="en">NFS <em>(Network File System)</em></span>















































distant quand une personne veut y accéder ; il peut fournir une méthode
alternative en cas où le système de fichier n&rsquo;est pas joignable. <br>
Vous aurez plus d&rsquo;informations en utilisant la commande &ldquo;<code>info amd</code>&rdquo;.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/amd" title="Page du Manuel OpenBSD pour : amd">amd</a>
</li>
</ul>
<h3 id="apmd">apmd</h3>
<p>Ce démon est responsable de la gestion de la frèquence 









<span lang="en">CPU <em>(Central Processing Unit)</em></span>





































































































. Il
est important de l&rsquo;exécuter sur une station de travail et spécifiquement sur un
portable ; il peut aussi déclencher automatiquement la mise en veille ou une
hibernation en cas de niveau de batterie bas.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/apmd" title="Page du Manuel OpenBSD pour : apmd">apmd</a>
, 
<a class="man" href="https://man.openbsd.org/apm" title="Page du Manuel OpenBSD pour : apm">apm</a>
</li>
</ul>
<h3 id="bgpd">bgpd</h3>
<p>C&rsquo;est le démon 





<span lang="en">BGP <em>(Border Gateway Protocol)</em></span>









































































































 qui est utilisé par les routeurs réseaux pour
échanger les routes avec d&rsquo;autres routeurs. C&rsquo;est ce qui fait principalement
qu&rsquo;Internet fonctionne ; chaque compagnie d&rsquo;hébergement annonce leurs ensembles
d&rsquo;adresses 


































<span lang="en">IP <em>(Internet Protocol)</em></span>












































































 et comment les atteindre, en retour, elles
reçoivent aussi les chemins pour se connecter à toutes les autres adresses.</p>
<ul>
<li>le <a href="http://www.openbgpd.org/" rel="external">site web d&rsquo;OpenBGPD</a></li>
</ul>
<h3 id="bootparamd">bootparamd</h3>
<p>Ce démon est utilisé pour le démarrage sans disque sur réseau ; il fournit
l&rsquo;information pour qu&rsquo;un client, tel un point de montage 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































,
utilise des dispositifs racine ou swap.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/diskless" title="Page du Manuel OpenBSD pour : diskless">diskless</a>
</li>
</ul>
<h3 id="cron">cron</h3>
<p>C&rsquo;est le démon qui lira la table de cron de chaque utilisateur et celles
du système afin d&rsquo;exécuter les commandes programmées. Les tables de cron
utilisateur sont modifiées par l&rsquo;usage de la commande <code>crontab</code>.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/cron" title="Page du Manuel OpenBSD pour : cron">cron</a>
, 
<a class="man" href="https://man.openbsd.org/crontab" title="Page du Manuel OpenBSD pour : crontab">crontab</a>
, 
<a class="man" href="https://man.openbsd.org/crontab.5" title="Page du Manuel OpenBSD pour : crontab">crontab(5)</a>
</li>
</ul>
<h3 id="dhcpd">dhcpd</h3>
<p>C&rsquo;est le serveur 












<span lang="en">DHCP <em>(Dynamic Host Control Protocol)</em></span>


































































































 utilisé pour fournir automatiquement des
adresses 




































<span lang="en">IPv4 <em>(Internet Protocol v4)</em></span>










































































 sur le réseau aux systèmes utilisant un client














<abbr lang="en" title="Dynamic Host Control Protocol">DHCP</abbr>


































































































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/dhcpd.8" title="Page du Manuel OpenBSD pour : dhcpd">dhcpd(8)</a>
</li>
</ul>
<h3 id="dhcpleased">dhcpleased</h3>
<p>C&rsquo;est un client 













<abbr lang="en" title="Dynamic Host Control Protocol">DHCP</abbr>


































































































 - <em>apparu sous OpenBSD 6.9</em> <sup>1</sup></p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/dhcpleased.8" title="Page du Manuel OpenBSD pour : dhcpleased">dhcpleased(8)</a>
</li>
</ul>
<h3 id="dhcrelay">dhcrelay</h3>
<p>C&rsquo;est un relais de requêtes 













<abbr lang="en" title="Dynamic Host Control Protocol">DHCP</abbr>


































































































, utilisé par une interface
réseau pour relayer les requêtes vers une autre interface.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/dhcrelay.8" title="Page du Manuel OpenBSD pour : dhcrelay">dhcrelay(8)</a>
</li>
</ul>
<h3 id="dvmrpd">dvmrpd</h3>
<p>Ce démon est un démon de routage multicast, au cas où vous auriez besoin
d&rsquo;un spanning multicast pour le déployer en dehors de votre 















































<span lang="en">LAN <em>(Local Area Network)</em></span>
































































local. <br>
Il est toutefois remplacé par 








































































<span lang="en">PIM <em>(Protocol-Independent Multicast)</em></span>






































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/dvmrpd.8" title="Page du Manuel OpenBSD pour : dvmrpd">dvmrpd(8)</a>
</li>
</ul>
<h3 id="eigrpd">eigrpd</h3>
<p>Ce démon est un protocol de routage à états de liens pour une passerelle
Internet ; il est comparable à 





































































<span lang="en">OSPF <em>(Open Shortest Path First)</em></span>









































 mais compatible avec CISCO.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/eigrpd.8" title="Page du Manuel OpenBSD pour : eigrpd">eigrpd(8)</a>
</li>
</ul>
<h3 id="ftpd">ftpd</h3>
<p>C&rsquo;est un serveur 























<span lang="en">FTP <em>(File Transfer Protocol)</em></span>























































































 fournissant beaucoup de fonctionnalités.
Bien que 
























<abbr lang="en" title="File Transfer Protocol">FTP</abbr>























































































 soit abandonné et obsolète (certainement parce qu&rsquo;il
n&rsquo;est pas pleinement fonctionnel dans le cas de 



























































<span lang="en">NAT <em>(Network Address Translation)</em></span>



















































), il peut
être utilisé pour fournir des accès en lecture et écriture anonymes sur un
répertoire (et bien d&rsquo;autres choses).</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ftpd.8" title="Page du Manuel OpenBSD pour : ftpd">ftpd(8)</a>
</li>
</ul>
<h3 id="ftpproxy">ftpproxy</h3>
<p>C&rsquo;est un démon proxy 
























<abbr lang="en" title="File Transfer Protocol">FTP</abbr>























































































 qui est un de ceux supposés être
fonctionnels par dessus 




























































<abbr lang="en" title="Network Address Translation">NAT</abbr>



















































 ; il ajoutera les règles








































































<span lang="en">PF <em>(Packet Filter)</em></span>







































 automatiquement afin de connecter les requêtes entrantes au
serveur derrière la 




























































<abbr lang="en" title="Network Address Translation">NAT</abbr>



















































. C&rsquo;est une partie de la folie

























<abbr lang="en" title="File Transfer Protocol">FTP</abbr>























































































.</p>
<h3 id="ftpproxy6">ftpproxy6</h3>
<p>La version 





































<span lang="en">IPv6 <em>(Internet Protocol v6)</em></span>









































































 du précédent. <br>
Utiliser 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































 derrière une 




























































<abbr lang="en" title="Network Address Translation">NAT</abbr>



















































 n&rsquo;a pas de sens.</p>
<h3 id="hostapd">hostapd</h3>
<p>C&rsquo;est le démon qui permet à OpenBSD de devenir un point d&rsquo;accès Wifi.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/hostapd.8" title="Page du Manuel OpenBSD pour : hostapd">hostapd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/hostapd.conf.5" title="Page du Manuel OpenBSD pour : hostapd.conf">hostapd.conf(5)</a>
</li>
</ul>
<h3 id="hotplugd">hotplugd</h3>
<p>hotplugd est un magnifique démon qui exécutera des actions lorsque des
dispositifs sont connectés ou déconnectés. <br>
Il pourrait être programmé pour exécuter automatiquement une sauvegarde si
certaines conditions sont remplies, comme l&rsquo;insertion d&rsquo;un disque









































































































<span lang="en">USB <em>(Universal Serial Bus)</em></span>






 correspondant à un nom connu ou comme le montage d&rsquo;un lecteur.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/hotplugd.8" title="Page du Manuel OpenBSD pour : hotplugd">hotplugd(8)</a>
</li>
</ul>
<h3 id="httpd">httpd</h3>
<p>httpd est le démon 






























<span lang="en">HTTP <em>(HyperText Transfer Protocol)</em></span>
















































































(S) qui supporte certaines fonctionnalités,
telles la prise en charge de FastCGI, la réécriture d&rsquo;







































































































<span lang="en">URL <em>(Uniform Resource Locator)</em></span>







 et






















































































<span lang="en">SNI <em>(Server Name Indication)</em></span>

























. <br>
Bien qu&rsquo;il n&rsquo;ait pas toutes les fonctionnalités d&rsquo;un serveur web tel nginx,
il est capable d&rsquo;héberger certains programmes PHP tels que nextcloud, roundcube
ou mediawiki.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/httpd.conf.5" title="Page du Manuel OpenBSD pour : httpd.conf">httpd.conf(5)</a>
</li>
</ul>
<h3 id="identd">identd</h3>
<p>identd est un démon pour le Protocole d&rsquo;Identification qui retourne le nom
de session pour un utilisateur qui a initié une connexion, qui peut être
utilisé sur 






































<span lang="en">IRC <em>(Internet Relay Chat)</em></span>








































































 pour authentifier l&rsquo;utilisateur.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/identd.8" title="Page du Manuel OpenBSD pour : identd">identd(8)</a>
</li>
</ul>
<h3 id="ifstated">ifstated</h3>
<p>C&rsquo;est le démon pour surveiller l&rsquo;état des interfaces réseaux et qui peut
mettre en place des actions lors de changements. Il peut être utiliser
pour déclencher des changements en cas où une interface perd sa connectivité.
Je l&rsquo;ai utiliser pour déclencher un changement de route pour un dispositif
4G dans le cas où un ping échoue par dessus l&rsquo;interface de liaison montante.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ifstated.8" title="Page du Manuel OpenBSD pour : ifstated">ifstated(8)</a>
, 
<a class="man" href="https://man.openbsd.org/ifstated.conf.5" title="Page du Manuel OpenBSD pour : ifstated.conf">ifstated.conf(5)</a>
</li>
</ul>
<h3 id="iked">iked</h3>
<p>C&rsquo;est le démon utilisé pour fournir une authentification IKEv2 afin d&rsquo;établir
un tunnel 



































<span lang="en">IPSec <em>(Internet Protocol Security)</em></span>











































































.</p>
<ul>
<li><a href="https://www.openbsd.org/faq/faq17.html" rel="external">OpenBSD FAQ VPN</a></li>
</ul>
<h3 id="inetd">inetd</h3>
<p>Ce démon est souvent oublié mais est très utile. inetd peut écouter
sur les ports 




























































































<span lang="en">TCP <em>(Transfer Control Protocol)</em></span>


















 ou 




































































































<span lang="en">UDP <em>(User Datagram Protocol)</em></span>










 et exécutera une commande
lors de la connexion à un port donné, des données entrantes seront passées à
l&rsquo;entrée standard d&rsquo;un programme et la sortie sera retournée au client. <br>
C&rsquo;est une manière facile de transformer un programme en programme réseau ;
il n&rsquo;est pas largement utilisé car il n&rsquo;est pas très évolutif.
En effet, le processus d&rsquo;exécution d&rsquo;un nouveau programme à chaque connexion
peut pousser un système à ses limites.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/inetd.8" title="Page du Manuel OpenBSD pour : inetd">inetd(8)</a>
</li>
</ul>
<h3 id="isakmpd">isakmpd</h3>
<p>Ce démon est utilisé pour fournir une authentification IKEv1 afin d&rsquo;établir
un tunnel 




































<abbr lang="en" title="Internet Protocol Security">IPSec</abbr>











































































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/isakmpd.8" title="Page du Manuel OpenBSD pour : isakmpd">isakmpd(8)</a>
</li>
</ul>
<h3 id="iscsid">iscsid</h3>
<p>Ce démon est un initiateur 








































<span lang="en">iSCSI <em>(Internet Small Computer System Interface)</em></span>






































































 qui connectera une cible










































<abbr lang="en" title="Internet Small Computer System Interface">iSCSI</abbr>






































































 (c&rsquo;est ainsi qu&rsquo;est appelé un dispositif de bloc réseau) et
l&rsquo;exposera localement en tant que dispositif <code>/dev/vcsi</code>. OpenBSD ne fournit
pas de démon de cible 









































<abbr lang="en" title="Internet Small Computer System Interface">iSCSI</abbr>






































































 dans son système de base mais il en
existe un dans les ports.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/iscsid.8" title="Page du Manuel OpenBSD pour : iscsid">iscsid(8)</a>
</li>
</ul>
<h3 id="ldapd">ldapd</h3>
<p>C&rsquo;est un serveur 
















































<span lang="en">LDAP <em>(Lightweight Directory Access Protocol)</em></span>






























































 léger, offrant la version 3 du protocole.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ldap" title="Page du Manuel OpenBSD pour : ldap">ldap</a>
, 
<a class="man" href="https://man.openbsd.org/ldapd.8" title="Page du Manuel OpenBSD pour : ldapd">ldapd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/ldapd.conf.5" title="Page du Manuel OpenBSD pour : ldapd.conf">ldapd.conf(5)</a>
</li>
</ul>
<h3 id="ldattach">ldattach</h3>
<p>Ce démon permet de configurer des programmes exposés sur le port série,
tels des dispositifs gps.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ldattach.8" title="Page du Manuel OpenBSD pour : ldattach">ldattach(8)</a>
</li>
</ul>
<h3 id="ldomd">ldomd</h3>
<p>Ce démon est spécifique à la plateforme sparc64 et fournit des services
pour la fonctionnalité dom.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ldomd.8" title="Page du Manuel OpenBSD pour : ldomd">ldomd(8)</a>
</li>
</ul>
<h3 id="ldpd">ldpd</h3>
<p>Ce démon est utilisé pour les routeurs 
























































<span lang="en">MPLS <em>(MultiProtocol Label Switching)</em></span>






















































 afin d&rsquo;obtenir des
labels.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ldpd.8" title="Page du Manuel OpenBSD pour : ldpd">ldpd(8)</a>
</li>
</ul>
<h3 id="lockd">lockd</h3>
<p>Ce démon est utilisé comme part de l&rsquo;environnement 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































 pour
supporter le verrouillage de fichiers.</p>
<h3 id="lpd">lpd</h3>
<p>Ce démon est utilisé pour gérer un accès à une imprimante.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/lpd.8" title="Page du Manuel OpenBSD pour : lpd">lpd(8)</a>
</li>
</ul>
<h3 id="mountd">mountd</h3>
<p>Ce démon est utilisé pour les clients distants 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































 afin d&rsquo;obtenir
l&rsquo;information sur ce que le système offre actuellement. La commande <code>showmount</code>
peut être utilisée pour voir ce qu&rsquo;expose mountd.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/mountd.8" title="Page du Manuel OpenBSD pour : mountd">mountd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/showmount.8" title="Page du Manuel OpenBSD pour : showmount">showmount(8)</a>
</li>
</ul>
<h3 id="mopd">mopd</h3>
<p>Ce démon est utilisé pour distribuer des images MOP, qui semble être relatif
aux architectures alpha et WAX.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/mopd.8" title="Page du Manuel OpenBSD pour : mopd">mopd(8)</a>
</li>
</ul>
<h3 id="mrouted">mrouted</h3>
<p>Identique à <a href="/fr/trad/solene-rapenne/openbsd-bases-services/#dvmrpd">dvmrpd</a>.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/mrouted.8" title="Page du Manuel OpenBSD pour : mrouted">mrouted(8)</a>
</li>
</ul>
<h3 id="nfsd">nfsd</h3>
<p>Ce serveur est utiliser pour servir les requêtes 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































 venant des
clients 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































. Des statistiques 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































 (client ou serveur)
peuvent être obtenues par la commande <code>nfsstat</code>.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/nfsd.8" title="Page du Manuel OpenBSD pour : nfsd">nfsd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/nfsstat" title="Page du Manuel OpenBSD pour : nfsstat">nfsstat</a>
</li>
</ul>
<h3 id="npppd">npppd</h3>
<p>Ce démon est utilisé pour établir une connexion par 










































































<span lang="en">PPP <em>(Point to Point Protocol)</em></span>





































mais peut aussi créer des tunnels avec les protocoles 














































<span lang="en">L2TP <em>(Layer 2 Tunneling Protocol)</em></span>
































































,













































































<span lang="en">PPTP <em>(Point-to-Point Tunneling Protocol)</em></span>


































 et 











































































<span lang="en">PPPoE <em>(Point-to-Point Protocol over Ethernet)</em></span>



































. <br>












































































<abbr lang="en" title="Point to Point Protocol">PPP</abbr>




































 est utilisé par certains modems pour se connecter à Internet.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/npppd.8" title="Page du Manuel OpenBSD pour : npppd">npppd(8)</a>
</li>
</ul>
<h3 id="nsd">nsd</h3>
<p>Ce démon est un serveur de nom 















<span lang="en">DNS <em>(Domain Name Service)</em></span>































































































 faisant autorité, ce qui
signifie qu&rsquo;il gère toutes les informations à-propos d&rsquo;un nom de domaine et de
ses sous-domaines. <br>
Il reçoit les requêtes depuis les serveurs récursifs, tels qu&rsquo;unbound ou
unwind, etc. <br>
Si vous voulez gérer un nom de domaine et que vous souhaitez le faire depuis
votre système, c&rsquo;est ce qu&rsquo;il vous faut.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/nsd.8" title="Page du Manuel OpenBSD pour : nsd">nsd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/nsd.conf.5" title="Page du Manuel OpenBSD pour : nsd.conf">nsd.conf(5)</a>
</li>
</ul>
<h3 id="ntpd">ntpd</h3>
<p>Ce démon est un service 


































































<span lang="en">NTP <em>(Network Time Protocol)</em></span>












































 qui permet de garder l&rsquo;horloge
système à l&rsquo;heure ; il peut utiliser des serveurs 



































































<abbr lang="en" title="Network Time Protocol">NTP</abbr>












































 ou des
senseurs (tels des 


























<span lang="en">GPS <em>(Global Positioning System)</em></span>




















































































) comme source de temps, mais aussi
supporter des serveurs distants afin de challenger vos sources de temps. Il
peut agir comme démon afin de fournir le temps aux autres clients




































































<abbr lang="en" title="Network Time Protocol">NTP</abbr>












































 .</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ntpd.8" title="Page du Manuel OpenBSD pour : ntpd">ntpd(8)</a>
</li>
</ul>
<h3 id="ospfd">ospfd</h3>
<p>C&rsquo;est un démon pour le protocole de routage 






































































<abbr lang="en" title="Open Shortest Path First">OSPF</abbr>









































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ospfd.8" title="Page du Manuel OpenBSD pour : ospfd">ospfd(8)</a>
</li>
</ul>
<h3 id="ospf6d">ospf6d</h3>
<p>La version 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































 du démon ci-dessus.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ospf6d.8" title="Page du Manuel OpenBSD pour : ospf6d">ospf6d(8)</a>
</li>
</ul>
<h3 id="pflogd">pflogd</h3>
<p>Ce démon reçoit les paquets depuis des règles 








































































<abbr lang="en" title="Packet Filter">PF</abbr>







































 correspondantes
au mot clé &ldquo;log&rdquo; et enregistrera les données dans un fichier journal qui peut
être réutiliser plus tard avec la commande <code>tcpdump</code>. <br>
Chaque paquet dans le fichier journal contient l&rsquo;information sur quelle règle
l&rsquo;a déclenché, ce qui est très pratique pour l&rsquo;analyse.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/pflogd.8" title="Page du Manuel OpenBSD pour : pflogd">pflogd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/tcpdump.8" title="Page du Manuel OpenBSD pour : tcpdump">tcpdump(8)</a>
</li>
</ul>
<h3 id="portmap">portmap</h3>
<p>Ce démon est utilisé en tant que partie de l&rsquo;environnement 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/portmap.8" title="Page du Manuel OpenBSD pour : portmap">portmap(8)</a>
</li>
</ul>
<h3 id="rad">rad</h3>
<p>Ce démon est utilisé sur les routeurs 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































 pour avertir des
routes, ainsi les clients peuvent automatiquement les obtenir.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/rad.8" title="Page du Manuel OpenBSD pour : rad">rad(8)</a>
</li>
</ul>
<h3 id="radiusd">radiusd</h3>
<p>Ce démon est utilisé pour offrir le protocole d&rsquo;authentification RADIUS.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/radiusd.8" title="Page du Manuel OpenBSD pour : radiusd">radiusd(8)</a>
</li>
</ul>
<h3 id="rarpd">rarpd</h3>
<p>Ce démon est utilisé pour les démarrages sans disque, qui aide à associer
une adresse 



<span lang="en">ARP <em>(Address Resolution Protocol)</em></span>











































































































 à une adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 et un nom d&rsquo;hôte.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/rarpd.8" title="Page du Manuel OpenBSD pour : rarpd">rarpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/diskless.8" title="Page du Manuel OpenBSD pour : diskless">diskless(8)</a>
</li>
</ul>
<h3 id="rbootd">rbootd</h3>
<p>Selon le manpage, il est dit &ldquo;rboot répond aux demandes de démarrage d&rsquo;une
station de travail Hewlett-Packard sur le 
















































<abbr lang="en" title="Local Area Network">LAN</abbr>































































&rdquo;.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/rbootd.8" title="Page du Manuel OpenBSD pour : rbootd">rbootd(8)</a>
</li>
</ul>
<h3 id="relayd">relayd</h3>
<p>Ce démon est utilisé pour accepter les connexions entrantes et les distribue
aux services en arrière plan.
Il prend en charge beaucoup de protocoles et peut agir de manière transparente ;
son but est d&rsquo;avoir un frontend qui délivrera les connexionx à un liste
de backend mais aussi de vérifier leurs statuts.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/relayctl.8" title="Page du Manuel OpenBSD pour : relayctl">relayctl(8)</a>
,  
<a class="man" href="https://man.openbsd.org/relayd.conf.5" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)</a>
</li>
</ul>
<h3 id="resolvd">resolvd</h3>
<p>C&rsquo;est un démon pour gérer la configuration du fichier <code>/etc/resolv.conf</code>,
qui contient les détails des noms de serveurs à interroger -
<em>apparu sous OpenBSD 6.9</em> <sup>1</sup></p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/resolvd.8" title="Page du Manuel OpenBSD pour : resolvd">resolvd(8)</a>
</li>
</ul>
<h3 id="ripd">ripd</h3>
<p>C&rsquo;est un démon de routage utilisant un vieux protocole largement supporté.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ripd.8" title="Page du Manuel OpenBSD pour : ripd">ripd(8)</a>
</li>
</ul>
<h3 id="route6d">route6d</h3>
<p>La version 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































 du service ci-dessus.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/route6d.8" title="Page du Manuel OpenBSD pour : route6d">route6d(8)</a>
</li>
</ul>
<h3 id="sasyncd">sasyncd</h3>
<p>Ce démon est utilisé pour garder les passerelles 




































<abbr lang="en" title="Internet Protocol Security">IPSec</abbr>












































































synchronisées, en cas de repli nécessaire. Il peut être utilisé avec les
dispositifs carp.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/sasyncd.8" title="Page du Manuel OpenBSD pour : sasyncd">sasyncd(8)</a>
</li>
</ul>
<h3 id="savecore">savecore</h3>
<p>Ce démon a pour propos de sauvegarder un core dump du système d&rsquo;exploitation.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/savecore.8" title="Page du Manuel OpenBSD pour : savecore">savecore(8)</a>
</li>
</ul>
<h3 id="sensorsd">sensorsd</h3>
<p>Ce démon recueille les informations de surveillance venant du matériel
tel la température ou le status du disque. Si une vérification excède un
niveau, une commande peut être exécutée.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/sensorsd.8" title="Page du Manuel OpenBSD pour : sensorsd">sensorsd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/sensorsd.conf.5" title="Page du Manuel OpenBSD pour : sensorsd.conf">sensorsd.conf(5)</a>
</li>
</ul>
<h3 id="slaacd">slaacd</h3>
<p>Ce service est un démon qui obtiendra automatiquement une configuration







































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































 sur le réseau.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/slaacd.8" title="Page du Manuel OpenBSD pour : slaacd">slaacd(8)</a>
</li>
</ul>
<h3 id="slowcgi">slowcgi</h3>
<p>Ce démon est utilisé pour exposer un programme 








<span lang="en">CGI <em>(Common Gateway Interface)</em></span>






































































































 en tant que
service FastCGI, permettant au serveur 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 <a href="/fr/trad/solene-rapenne/openbsd-bases-services/#httpd">httpd</a>
d&rsquo;exécuter du 









<abbr lang="en" title="Common Gateway Interface">CGI</abbr>






































































































. C&rsquo;est l&rsquo;équivalent d&rsquo;<a href="/fr/trad/solene-rapenne/openbsd-bases-services/#inetd">inetd</a> pour
FastCGI.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/slowcgi.8" title="Page du Manuel OpenBSD pour : slowcgi">slowcgi(8)</a>
</li>
</ul>
<h3 id="smtpd">smtpd</h3>
<p>Ce démon est le serveur 




















































































<span lang="en">SMTP <em>(Simple Mail Transfer Protocol)</em></span>


























 qui sera utilisé pour délivrer des
mails localement ou vers un serveur mails distant.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/smtpd.8" title="Page du Manuel OpenBSD pour : smtpd">smtpd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/smtpctl.8" title="Page du Manuel OpenBSD pour : smtpctl">smtpctl(8)</a>
,  
<a class="man" href="https://man.openbsd.org/smtpd.conf.5" title="Page du Manuel OpenBSD pour : smtpd.conf">smtpd.conf(5)</a>
</li>
</ul>
<h3 id="sndiod">sndiod</h3>
<p>C&rsquo;est un démon gérant le son depuis de nombreuses sources. Il prend en
charge l&rsquo;envoi de son local vers un serveur sndiod distant.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/sndiod.8" title="Page du Manuel OpenBSD pour : sndiod">sndiod(8)</a>
,  
<a class="man" href="https://man.openbsd.org/sndioctl" title="Page du Manuel OpenBSD pour : sndioctl">sndioctl</a>
,  
<a class="man" href="https://man.openbsd.org/mixerctl.8" title="Page du Manuel OpenBSD pour : mixerctl">mixerctl(8)</a>
</li>
<li><a href="https://www.openbsd.org/faq/faq13.html" rel="external">OpenBSD FAQ Multimedia</a></li>
</ul>
<h3 id="snmpd">snmpd</h3>
<p>Ce démon est un serveur 






















































































<span lang="en">SNMP <em>(Simple Network Management Protocol)</em></span>
























 exposant certaines métriques système
à un client 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/snmpd.8" title="Page du Manuel OpenBSD pour : snmpd">snmpd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/snmpd.conf.5" title="Page du Manuel OpenBSD pour : snmpd.conf">snmpd.conf(5)</a>
</li>
</ul>
<h3 id="spamd">spamd</h3>
<p>Ce démon agit comme un faux serveur qui délaiera, bloquera ou laissera passer
des courriels selon certaines règles. Il peut être utilisé pour ajouter
une adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 à une liste de blocage, qui essaie d&rsquo;envoyer un
courriel à une adresse spécifique (tel qu&rsquo;un &ldquo;pot de miel&rdquo;), de transmettre des
courriels depuis des serveurs figurant dans une liste d&rsquo;acceptation ou de délayer
des connexions depuis des serveurs inconnus (liste grise) pour qu&rsquo;ils se
reconnectent plusieurs fois avant de transmettre le mail au serveur






















































































<abbr lang="en" title="Simple Mail Transfer Protocol">SMTP</abbr>


























. <br>
C&rsquo;est un moyen assez efficace d&rsquo;empêcher le spam, mais perd de sa pertinence
lorsque l&rsquo;envoyeur utilise de larges ensembles d&rsquo;adresses 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 pour
envoyer des courriels, signifiant que si vous essayer de recevoir un mail depuis
un gros serveur, vous bloquerez le serveur X.Y.Z.1, mais X.Y.Z.2 essaiera
et ainsi de suite, résultat aucun ne passera la liste grise.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/spamd.8" title="Page du Manuel OpenBSD pour : spamd">spamd(8)</a>
</li>
</ul>
<h3 id="spamlogd">spamlogd</h3>
<p>Ce démon est dédié pour la mise à jour de liste d&rsquo;acceptation de <a href="/fr/trad/solene-rapenne/openbsd-bases-services/#spamd">spamd</a>.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/spamlogd.8" title="Page du Manuel OpenBSD pour : spamlogd">spamlogd(8)</a>
</li>
</ul>
<h3 id="sshd">sshd</h3>
<p>C&rsquo;est le bien connu serveur 
























































































<span lang="en">SSH <em>(Secure SHell)</em></span>






















. Permettre les connexions
sécurisées vers un shell depuis un client distant. Il a beaucoup de
fonctionnalités qui gagneraient à être connues, telles que les commandes de
restriction par clé publique dans les fichiers <code>~/.ssh/authorized_keys</code> ou



















































































<span lang="en">SFTP <em>(SSH File Transfer Protocol)</em></span>




























 permettant seuls les accès chrootés.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/sshd.8" title="Page du Manuel OpenBSD pour : sshd">sshd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/sshd_config.5" title="Page du Manuel OpenBSD pour : sshd_config">sshd_config(5)</a>
</li>
</ul>
<h3 id="statd">statd</h3>
<p>Ce démon est utilisé dans un environnement 

































































<abbr lang="en" title="Network File System">NFS</abbr>














































 gérant <a href="/fr/trad/solene-rapenne/openbsd-bases-services/#lockd">lockd</a>
afin de vérifier si l&rsquo;hôte distant est toujours en vie.</p>
<h3 id="switchd">switchd</h3>
<p>Ce démon est utilisé pour contrôler un pseudo dispositif de commutation;</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/switchd.8" title="Page du Manuel OpenBSD pour : switchd">switchd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/switchctl.8" title="Page du Manuel OpenBSD pour : switchctl">switchctl(8)</a>
,  
<a class="man" href="https://man.openbsd.org/switch.4" title="Page du Manuel OpenBSD pour : switch">switch(4)</a>
</li>
</ul>
<h3 id="syslogd">syslogd</h3>
<p>C&rsquo;est le serveur de journalisation qui reçoit les messages depuis les
programmes locaux et les enregistrent en accord avec le fichier journal.
Il peut être configuré pour capturer certains messages depuis des commandes,
des programmes tels que sshlockout qui utilise cette méthode pour apprendre
quelle adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 doit être bloquée, mais peut aussi écouter sur
le réseau afin d&rsquo;aggréger les journaux d&rsquo;autres machines. <br>
Le programme <code>newsyslog</code> est utilisé pour faire une rotation des fichiers
(déplacer un fichier, le compresser et permettre la création d&rsquo;un nouveau
et supprimer aussi les anciennes archives). Un script peut utiliser la
commande <code>logger</code> pour envoyer du texte au syslog.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/syslogd.8" title="Page du Manuel OpenBSD pour : syslogd">syslogd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/syslog.conf.5" title="Page du Manuel OpenBSD pour : syslog.conf">syslog.conf(5)</a>
,  
<a class="man" href="https://man.openbsd.org/newsyslog.8" title="Page du Manuel OpenBSD pour : newsyslog">newsyslog(8)</a>
,

    <a class="man" href="https://man.openbsd.org/logger" title="Page du Manuel OpenBSD pour : logger">logger</a>
</li>
</ul>
<h3 id="tftpd">tftpd</h3>
<p>Ce démon est le serveur 





























































































<span lang="en">TFTP <em>(Trivial File Transfer Protocol)</em></span>

















, utilisé afin de fournir des noyaux
sur le réseau pour les machines sans disques ou pousser des fichiers aux
appareils.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/diskless.8" title="Page du Manuel OpenBSD pour : diskless">diskless(8)</a>
</li>
</ul>
<h3 id="tftpproxy">tftpproxy</h3>
<p>Ce démon est utilisé pour manipuler le parefeu 








































































<abbr lang="en" title="Packet Filter">PF</abbr>







































 afin de relayer
les requêtes 






























































































<abbr lang="en" title="Trivial File Transfer Protocol">TFTP</abbr>

















 vers un serveur 






























































































<abbr lang="en" title="Trivial File Transfer Protocol">TFTP</abbr>

















.</p>
<h3 id="unbound">unbound</h3>
<p>Ce démon est un serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 récursif ; c&rsquo;est le type de serveur
listé dans le fichier <code>/etc/resolv.conf</code> qui est responsable de traduire un nom
de domaine pleinement qualifié à l&rsquo;adresse IP correspondante, en demandant
un serveur à la fois, par exemple en demandant le serveur <a href="https://www.dataswamp.org" rel="external">www.dataswamp.org</a>,
il est requis de demander au serveur faisant autorité .org où est le serveur
faisant autorité pour dataswamp (faisant partie du domaine supérieur .org),
puis le serveur DNS dataswamp.org sera interrogé pour savoir quelle est
l&rsquo;adresse IP de <a href="https://www.dataswamp.org" rel="external">www.dataswamp.org</a>. <br>
Il peut aussi garder les requêtes en cache et valide les requêtes et les
réponses ; c&rsquo;est une bonne idée d&rsquo;avoir un tel serveur sur un 
















































<abbr lang="en" title="Local Area Network">LAN</abbr>
































































ayant beaucoup de clients pour lesquels partager un cache de requêtes.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/unbound.8" title="Page du Manuel OpenBSD pour : unbound">unbound(8)</a>
,  
<a class="man" href="https://man.openbsd.org/unbound.conf.5" title="Page du Manuel OpenBSD pour : unbound.conf">unbound.conf(5)</a>
</li>
</ul>
<h3 id="unwind">unwind</h3>
<p>Ce démon est un serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 récursif local qui fera de son mieux
pour donner des réponses valides ; il est conçu pour les utilisateurs nomades
qui peuvent rencontrer des environnements hostiles tels que des portails
captifs ou un serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 par 













<abbr lang="en" title="Dynamic Host Control Protocol">DHCP</abbr>


































































































 empêchant le
fonctionnement de 
















<span lang="en">DNSSEC <em>(Domain Name System Security Extensions)</em></span>






























































































, etc. <br>
unwind interroge certaines sources 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 (récursif à partir des
serveurs racines, fourni par 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































, stub ou un serveur





















<span lang="en">DoT <em>(DNS-over-TCP)</em></span>


























































































 depuis un fichier de configuration) régulièrement et choisit
le plus rapide. <br>
Il agira aussi comme cache local et ne peut écouter sur le réseau pour ne
pas être utilisé par d&rsquo;autres clients. Il prend en charge aussi une liste
bloquante de domaines en entrée.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/unwind.8" title="Page du Manuel OpenBSD pour : unwind">unwind(8)</a>
,  
<a class="man" href="https://man.openbsd.org/unwindctl.8" title="Page du Manuel OpenBSD pour : unwindctl">unwindctl(8)</a>
,  
<a class="man" href="https://man.openbsd.org/unwind.conf.5" title="Page du Manuel OpenBSD pour : unwind.conf">unwind.conf(5)</a>
</li>
</ul>
<h3 id="vmd">vmd</h3>
<p>C&rsquo;est le démon qui permet d&rsquo;exécuter des machines virtuelles utilisant vmm.
Depuis OpenBSD 6.4, il est capable de faire fonctionner des invités OpenBSD
et Linux, sans interface graphique, et avec un seul cœur.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/vmd.8" title="Page du Manuel OpenBSD pour : vmd">vmd(8)</a>
,  
<a class="man" href="https://man.openbsd.org/vmd.conf.5" title="Page du Manuel OpenBSD pour : vmd.conf">vmd.conf(5)</a>
,  
<a class="man" href="https://man.openbsd.org/vmctl.8" title="Page du Manuel OpenBSD pour : vmctl">vmctl(8)</a>
,

    <a class="man" href="https://man.openbsd.org/vmm.4" title="Page du Manuel OpenBSD pour : vmm">vmm(4)</a>
</li>
<li><a href="https://www.openbsd.org/faq/faq16.html" rel="external">OpenBSD FAQ Virtualization</a></li>
</ul>
<h3 id="watchdogd">watchdogd</h3>
<p>Ce démon est utilisé pour déclencher les timers watchdog, s&rsquo;il y en a.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/watchdogd.8" title="Page du Manuel OpenBSD pour : watchdogd">watchdogd(8)</a>
</li>
</ul>
<h3 id="wsmoused">wsmoused</h3>
<p>Ce démon est utilisé pour fournir la prise en charge de la souris à la console.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/wsmoused.8" title="Page du Manuel OpenBSD pour : wsmoused">wsmoused(8)</a>
</li>
</ul>
<h3 id="xenodm">xenodm</h3>
<p>Ce démon est utilisé pour démarrer le serveur X et permettre aux utilisateurs
leur propre authentification et se connecter à leur session.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/xenodm" title="Page du Manuel OpenBSD pour : xenodm">xenodm</a>
</li>
</ul>
<h3 id="ypbind">ypbind</h3>
<p>Ce démon est utilisé avec un serveur de Pages Jaunes (















































































































<span lang="en">YP <em>(Yellow Page)</em></span> pour
garder et maintenir un fichier d&rsquo;informations.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ypbind.8" title="Page du Manuel OpenBSD pour : ypbind">ypbind(8)</a>
</li>
</ul>
<h3 id="ypldap">ypldap</h3>
<p>Ce démon offre un service (
















































































































<abbr lang="en" title="Yellow Page">YP</abbr> en utilisant un backend


















































<abbr lang="en" title="Lightweight Directory Access Protocol">LDAP</abbr>






























































.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ypldap.8" title="Page du Manuel OpenBSD pour : ypldap">ypldap(8)</a>
</li>
</ul>
<h3 id="ypserv">ypserv</h3>
<p>Ce démon est un serveur (
















































































































<abbr lang="en" title="Yellow Page">YP</abbr>.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ypserv.8" title="Page du Manuel OpenBSD pour : ypserv">ypserv(8)</a>
</li>
</ul>
<hr>
<p><strong>FIN</strong></p>
<hr>
<h2 id="notes-de-traduction">Notes de Traduction</h2>
<ul>
<li><sup>1</sup> cette information n&rsquo;est pas disponible sur l&rsquo;article originel.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction du Tutoriel EN → FR &#39;Full list of services offered by a default OpenBSD installation&#39; - article de Solène Rapenne - expliquant les différents services par défaut sous OpenBSD]]></summary>
        <published>2021-05-07T15:08:51+02:00</published>
        <updated>2025-11-18T16:07:44+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f5bdd635-a3fd-21ea-efbb-38bac3a42d66</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/solene-rapenne/openbsd-getting-started/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : pour (bien) commencer !</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Sécurité" scheme="http://doc.huc.fr.eu.org/fr/tags/s%C3%A9curit%C3%A9/" />
        <category term="6.9" scheme="http://doc.huc.fr.eu.org/fr/tags/6.9/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="https://dataswamp.org/~solene/2021-05-03-openbsd-getting-started.html" rel="external">OpenBSD: getting started</a></strong>&rdquo;, écrit par Solène Rapenne.</p>
<hr>
<h2 id="introduction">Introduction</h2>
<p>Ceci est un guide pour les débutants sous OpenBSD ; j&rsquo;espère que cet article
deviendra une ressource utile pour aider les gens à se familiariser avec
ce système d&rsquo;exploitation que j&rsquo;adore. Je vais utiliser beaucoup de liens
parce que je préfère me référer à la documentation officielle.</p>
<p>Si vous êtes nouveau sous OpenBSD, vous êtes bienvenue, ce guide est pour
vous. Si vous ne l&rsquo;êtes pas, et bien, vous pourriez apprendre plusieurs
choses.</p>
<h2 id="étapes-dinstallation">Étapes d&rsquo;installation</h2>
<p>Cet article n&rsquo;a pas pour propos d&rsquo;expliquer comment installer OpenBSD.
Il y a assez de documentation officielle pour cela.</p>
<ul>
<li><a href="https://www.openbsd.org/faq/faq4.html" rel="external">OpenBSD FAQ about installation</a></li>
</ul>
<h2 id="premier-démarrage">Premier démarrage</h2>
<p>Ainsi, vous avez installé OpenBSD ; maintenant vous devez choisir d&rsquo;activer
X (l&rsquo;interface graphique au démarrage) et vous avez face à vous un terminal
sur un fond gris. Plusieurs choses deviennent intéressant ici.</p>
<h3 id="devenir-administrateur-root">Devenir administrateur (root)</h3>
<p>Vous allez souvent avoir besoin d&rsquo;utiliser le compte root pour diverses
commande ou modifier des fichiers systèmes.</p>
<p><code>$ su -l</code></p>
<p>Vous allez devoir entrer le mot de passe root (défini lors de l&rsquo;installation)
afin de changer d&rsquo;utilisateur. Si vous tapez la commande &ldquo;<code>whoami</code>&rdquo;, alors
vous devriez voir &ldquo;root&rdquo; comme résultat.</p>
<h3 id="vous-avez-un-courriel">Vous avez un courriel</h3>
<p>Quand vous installez le système (ou le mettez à jour), vous aurez un courriel
dans le compte root ; vous pouvez le lire par l&rsquo;usage de la commande &ldquo;<code>mail</code>&rdquo;.
C&rsquo;est un mail venant de Theo De Raadt (fondateur d&rsquo;OpenBSD) vous remerciant.</p>
<p>Vous remarquerez que ce courriel contient des indications, et a basiquement
le même propos que mon article - celui que vous êtes en train de lire.
Une page de manuel importante à lire est afterboot(8).</p>

<a class="man" href="https://man.openbsd.org/afterboot.8" title="Page du Manuel OpenBSD pour : afterboot">afterboot(8)</a>

<h3 id="quest-ce-quun-manpage-">Qu&rsquo;est-ce qu&rsquo;un manpage ?</h3>
<p>Si vous ne savez pas ce qu&rsquo;est un manpage (ou une page de manuel), c&rsquo;est
vraiment le moment de l&rsquo;apprendre parce que vous en aurez besoin. Quand
quelqu&rsquo;un dit un &ldquo;<code>man page</code>&rdquo;, cela implique &ldquo;une page de manuel&rdquo;.
La documentation dans OpenBSD est faite de pages de manuels relatifs à de
nombreux logiciels, concepts ou fonctions du langage C.</p>
<p>Pour lire un manpage, tapez dans un terminal (ou une console) &ldquo;<code>man afterboot</code>&rdquo;,
et utilisez les flèches de votre clavier (ou les touches page haut ou bas)
à l&rsquo;intérieur du manpage. Vous pouvez lire le &ldquo;<code>man man</code>&rdquo; à-propos du manpage man.</p>
<p>Précédemment, j&rsquo;ai écrit &ldquo;afterboot(8)&rdquo; mais le nom réel du manpage est
&ldquo;afterboot&rdquo;, le &ldquo;(8)&rdquo; permet de spécifier la section du manpage.
Certains mots peuvent être utilisé dans des contextes variés, selon la section
où ils sont placés. Par exemple, il y a sysctl(2) qui est la documentation
des appels systèmes &ldquo;sysctl()&rdquo;, là où sysctl(8) vous donnera les informations
à-propos de la commande sysctl afin de changer des paramètres noyaux.
Vous pouvez spécifier quelle section vous désirez lire en tapant le numéro
avant le nom de la page, tel que &ldquo;<code>man 2 sysctl</code>&rdquo; ou &ldquo;<code>man 8 sysctl</code>&rdquo;.</p>
<p>Les manpages sont construits de la même manière : NAME, SYNOPSIS, DESCRIPTION…
SEE ALSO… ; la section &ldquo;SEE ALSO&rdquo; est une section importante, qui vous
donne en références d&rsquo;autres manpages que vous pouvez lire.
Par exemple, afterboot(8) vous donne les indications à-propos de doas(1),
pkg_add(1), hier(7) et beaucoup d&rsquo;autres pages.</p>
<p>Maintenant, vous devriez être capable d&rsquo;utiliser les pages de manuels.</p>
<h2 id="installer-un-environnement-de-bureau">Installer un environnement de bureau</h2>
<p>Si vous voulez installer un environnement de bureau, il vous est offert
un &ldquo;meta paquet&rdquo; qui récupérera tous les paquets requis pour que l&rsquo;environnement
fonctionne.</p>
<p>OpenBSD fournit certains environnements de bureau, tels que :</p>
<ul>
<li>
<p>Gnome 3 ⇒ <code>pkg_add gnome</code></p>
</li>
<li>
<p>Xfce ⇒ <code>pkg_add xfce</code></p>
</li>
<li>
<p>MATE ⇒ <code>pkg_add mate</code></p>
</li>
</ul>
<p>Quand vous installez un paquet utilisant la commande &ldquo;<code>pkg_add</code>&rdquo;, vous aurez
peut-être un message final vous informant qu&rsquo;il y a un fichier à lire dans le
répertoire /usr/local/share/doc/pkg-readmes/ ; ces fichiers sont spécifiques
aux paquets et contiennent des instructions qu&rsquo;il faut lire avant d&rsquo;utiliser
un paquet.</p>
<p>Ces instructions peuvent être relatives à la performance, à des problèmes
potentielles de limites, des bouts de configuration, comment initier le
service, etc… Il est très important de les lire, et dans le cas d&rsquo;un
environnement de bureau, ils vous diront tout ce qu&rsquo;il faut savoir pour
le faire démarrer.</p>
<h2 id="session-graphique">Session graphique</h2>
<p>Quand vous vous connectez depuis l&rsquo;écran de connexion de xenodm (celui
où vous avez le poisson globe et le logo OpenBSD qui vous demande votre
identifiant et mot de passe de connexion), le programme xenodm lira votre
fichier ~/.xsession, là où vous avez préparez votre environnement de bureau
et les commandes à exécuter.
Habituellement, la première commande bloquante (celle qui continue de s&rsquo;exécuter
au premier plan) est votre gestionnaire de fenêtres ; vous pouvez placez
des commandes avant, afin de paramétrer votre système ou d&rsquo;exécuter des
programmes en arrière-plan.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># désactiver bell</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xset b off</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># auto blank après 10 minutes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xset s 600 600</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># exécuter xclock et xload</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xclock -geometry 75x75-70-0 -padding 1 &amp;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xload -nolabel -update 5 -geometry 75x75-145-0 &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># charger le fichier ~/.profile file pour définir ENV</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">. ~/.profile</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># afficher des notifications</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">dunst &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># charger des changements dans les paramètres du serveur X</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xrdb -merge ~/.Xresources</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diminuer la couleur bleue</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">sct 5600</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># synchroniser les tampons de copie</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">autocutsel &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># kdeconnect pour contrôler un smartphone Android</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">kdeconnect-indicator &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># réduire le son par défaut</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">sndioctl -f snd/1 output.level</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0.3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># le compositeur pour dessiner plus rapidement les fenêtres</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">picom &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># certains paramètres pour ma souris</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xset mouse 1 1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xinput set-prop 8 273 1.1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># exécuter mon gestionnaire de fenêtres</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fvwm2</span>
</span></span></code></pre></div><h2 id="configurer-votre-shell">Configurer votre shell</h2>
<p>C&rsquo;est une question vraiment récurrente : comment faire pour que les alias
de votre shell fonctionnent une fois que vous vous êtes connecté ?
Pour les shells bash, sh, et ksh (et peut-être d&rsquo;autres shells), à chaque
fois que vous créez un nouveau shell interactif (dans lequel vous pouvez
entrer des commandes), la variable d&rsquo;environnement ENV sera lue et si sa
valeur correspond à un chemin de fichier, il sera chargé.</p>
<p>La conception de votre environnement shell préféré est la suivante :</p>
<ul>
<li>
<p>le fichier ~/.xsession qui sourcera le fichier ~/.profile lors du démarrage
de X, héritant du contenu de tout ce qui est exécuté à partir de X</p>
</li>
<li>
<p>le fichier ~/.profile qui exportera ENV tel que &ldquo;<code>export ENV=~/.myshellfile</code>&rdquo;</p>
</li>
</ul>
<h2 id="échelle-automatique-de-la-fréquence-du-cpu">Échelle automatique de la fréquence du CPU</h2>
<p>Si vous avez un ordinateur commun (architecture amd64), vous voudrez exécuter
le service &ldquo;apmd&rdquo; en mode automatique ; il maintiendra votre CPU à la fréquence
la plus basse et augmentera la fréquence lorsque vous aurez une certaine charge,
ce qui permettra de réduire la chaleur, la consommation d&rsquo;énergie et le bruit.</p>
<p>Voici les commandes à exécuter en tant que root :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable apmd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set apmd flags -A</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start apmd</span>
</span></span></code></pre></div><h2 id="que-sont--release-et--stable-">Que sont -release et -stable ?</h2>
<p>Pour faire simple, la version &ldquo;-release&rdquo; est l&rsquo;ensemble des fichiers pour
installer OpenBSD dans cette version quand elle sort. D&rsquo;autres mises à jour
pour cette version sont appelés la branche -stable ; si vous exécutez
&ldquo;<code>pkg_add -u</code>&rdquo; pour mettre à jour vos paquets et &ldquo;<code>syspatch</code>&rdquo; pour mettre
à jour la base de votre système, vous suivrez automatiquement la branche
stable (ce qui est bien !). Release est un état unique à un moment précis
de l&rsquo;état d&rsquo;OpenBSD.</p>
<h2 id="faq-rapide">FAQ Rapide</h2>
<h3 id="où-est-steam-">Où est steam ?</h3>
<p>Pas de steam ; c&rsquo;est propriétaire et ne peut être exécuter sous OpenBSD.</p>
<h3 id="où-est-wine-">Où est wine ?</h3>
<p>Pas de wine ; cela requiert des changements dans le noyau.</p>
<h3 id="est-ce-que-ma-récente-carte-nvidia-fonctionne-">Est-ce que ma récente carte NVIDIA fonctionne ?</h3>
<p>Pas de pilote nvidia ; cela pourrait fonctionner mais avec le pilote VESA,
cela sera vraiment très lent.</p>
<h3 id="est-ce-que-lémulation-linux-fonctionne-">Est-ce que l&rsquo;émulation Linux fonctionne ?</h3>
<p>Il n&rsquo;y a pas d&rsquo;émulation Linux.</p>
<h3 id="je-veux-que-mon-programme-favori-fonctionne-sous-openbsd">Je veux que mon programme favori fonctionne sous OpenBSD</h3>
<p>S&rsquo;il n&rsquo;est pas Open Source et n&rsquo;utilise pas un langage tel Java ou C# qui
utilise une Machine Virtuelle de Langage, calque d&rsquo;abstratction pour fonctionner,
il ne fonctionnera pas (et la plupart des programmes ne sont pas ainsi).</p>
<p>S&rsquo;il est Open Source, cela peut être possible si toutes ses dépendances
sont disponibles pour OpenBSD.</p>
<ul>
<li><a href="https://www.openbsd.org/faq/ports/" rel="external">Get into the ports tree to make things run on OpenBSD</a></li>
</ul>
<h3 id="puis-je-avoir-sudo-">Puis-je avoir sudo ?</h3>
<p>OpenBSD est livré avec une alternative à sudo nommé &ldquo;doas&rdquo; dans le système
de base, mais sudo peut être installé en tant que paquet.</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/doas" title="Page du Manuel OpenBSD pour : doas">doas</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/doas.conf" title="Page du Manuel OpenBSD pour : doas.conf">doas.conf</a>
</li>
</ul>
<h3 id="comment-voir-la-liste-des-paquets">Comment voir la liste des paquets</h3>
<p>Vous pouvez vérifier le répertoire des paquets depuis un miroir ou visitez :</p>
<ul>
<li><a href="https://openports.pl/" rel="external">Openports.pl (qui utilise la version de développement de l&rsquo;arborescence des ports)</a></li>
</ul>
<h3 id="quel-outil-de-virtualisation-avez-vous-">Quel outil de virtualisation avez-vous ?</h3>
<p>Le système de virtualisation d&rsquo;OpenBSD peut exécuter OpenBSD et certaines
distributions Linux mais sans interface graphique et avec un seul CPU.
Cela signifie que vous aurez à configurer une console série afin de procéder
à l&rsquo;installation puis d&rsquo;utiliser ssh ou la console série pour utiliser
votre système.</p>
<p>qemu est dans les ports mais il n&rsquo;est pas accéléré et ne correspondra pas
aux besoins de la plupart des personnes car il est terriblement lent.</p>
<hr>
<p><strong>FIN</strong></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction du Tutoriel EN → FR &#39;OpenBSD: getting started&#39; expliquant ce qu&#39;il savoir pour bien commencer sous OpenBSD, selon Solène Rapenne]]></summary>
        <published>2021-05-05T14:21:10+02:00</published>
        <updated>2025-11-18T16:07:44+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:fe3fc0d8-887a-39a1-bf02-c01c086cbcd9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-relayd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Astuces relayd (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="relayd" scheme="http://doc.huc.fr.eu.org/fr/tags/relayd/" />
        <content type="html"><![CDATA[<h2 id="anti-floc">Anti-FLoC</h2>
<p>FLoC est une nouvelle technique de pistage développée par Google…</p>
<p>Ajoutez la règle suivante :</p>
<p><code>match response header set &quot;Permissions-Policy&quot; value &quot;interest-cohort=()&quot;</code></p>
<h2 id="httpoxy">HTTPoxy</h2>
<p>La faille HTTPoxy utilise l&rsquo;entête HTTP non standardisée, non conforme, nommée PROXY.
Pour en savoir plus sur cette faille : <a href="https://httpoxy.org" rel="external">https://httpoxy.org</a></p>
<p>Pour la bloquer, il faut modifier votre filtre <code>httpfilter</code>, en ajoutant :</p>
<p><code>match request header remove &quot;Proxy&quot;</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour le serveur relayd sous OpenBSD]]></summary>
        <published>2021-04-13T19:10:49+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:54494a07-19f3-9e49-2f33-b03c987eb280</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-image-avif/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx gère les images au format AVIF</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="image" scheme="http://doc.huc.fr.eu.org/fr/tags/image/" />
        <category term="avif" scheme="http://doc.huc.fr.eu.org/fr/tags/avif/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il y a quelques semaines, j&rsquo;ai écris l&rsquo;article sur la gestion des <a class="inside" href="/fr/web/nginx/nginx-image-webp/" title="Lien interne vers l&#39;article : 'Nginx gère les images au format Webp'">images webp par nginx</a>
.</p>
<p>Actuellement, un récent format d&rsquo;image apparaît, le format <abbr title="AV1 Image Format">AVIF</abbr>
.
Ainsi les images compressées dans ce format sont encore plus légères que
le format Webp <em>(bien sûr, généralement, cela dépend fortement des taux
de qualités de compression utilisés)</em>.</p>
<h3 id="support-web">Support web</h3>
<p>Actuellement seules les versions des clients suivants prennent en charge
ce format AVIF :</p>
<ul>
<li>le navigateur web Chromium, et son pendant non libre dixit
Google Chrome, depuis la version 85</li>
<li>le navigateur web Opera, depuis sa version 71</li>
<li>quant à Firefox, officiellement, avec sa version 86, sortie le 23/02/2021.
<em>Pour ceux qui migrent d&rsquo;une ancienne version, il faut activer le paramètre <code>image.avif.enabled</code>
sur <code>true</code> dans la configuration…</em></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Bref, cela nécessite d&rsquo;installer sur votre système d&rsquo;exploitation la
bibliothèque nécessaire :</p>
<ul>
<li>De(bi|vu)an : le paquet <strong>libavif-bin</strong></li>
<li>OpenBSD : le paquet <strong>libavif</strong></li>
</ul>
<p>qui installera principalement le binaire <code>avifenc</code> dont nous avons besoin.</p>
<h3 id="note-debian-stable">Note Debian Stable</h3>
<p>Malheureusement, sous De(bi|vu)an Stable, il semble manquer le support de
la libyuv, ce qui empêchera bien des images d&rsquo;être converties !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ avifenc --help
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Version: 0.8.4 <span style="color:#5bc4bf">(</span>dav1d <span style="color:#5bc4bf">[</span>dec<span style="color:#5bc4bf">]</span>:0.7.1, libgav1 <span style="color:#5bc4bf">[</span>dec<span style="color:#5bc4bf">]</span>:0.16.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>libyuv : unavailable
</span></span></code></pre></div><h3 id="note-cavif">Note cavif</h3>
<p>Heureusement, il existe le programme <strong><a href="https://github.com/kornelski/cavif-rs" rel="external">cavif</a></strong>,
écrit en langage Rust.
Reste plus qu&rsquo;à télécharger la version .deb fournie :
<a href="https://github.com/kornelski/cavif-rs/releases" rel="external">https://github.com/kornelski/cavif-rs/releases</a></p>
<h3 id="note-imagemagick">Note ImageMagick</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>ImageMagick est aussi capable de convertir une image au format AVIF :</p>
<p><code>$ convert &quot;${file}&quot; &quot;${file}.avif&quot;</code></p>
<p>Mais il semble qu&rsquo;il faille attendre les versions 7.x pour que ce soit
correctement géré !</p>
</div>

<hr>
<p><em>Bien-sûr, il existe d&rsquo;autres logiciels capable de convertir au format AVIF.
Au dernière nouvelle, Gimp 2.10.x en est capable.</em></p>
<h2 id="utilisation">Utilisation</h2>
<p>Il est ainsi possible de transformer les images gif, jpg, png et tiff.</p>
<p>La génération de l&rsquo;image au format AVIF peut prendre un certain temps,
plus ou moins considérable, selon les options choisies et le poids de
l&rsquo;image source à convertir !</p>
<h3 id="avifenc">avifenc</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ avifenc -s <span style="color:#f99b15">0</span> --min <span style="color:#f99b15">25</span> --max <span style="color:#f99b15">35</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.avif&#34;</span>
</span></span></code></pre></div><h3 id="cavif">cavif</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cavif --quality <span style="color:#f99b15">50</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> --output <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.avif&#34;</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Attention, par défaut, cavif ne réécrit pas sur un fichier AVIF déjà existant.
Soit vous utilisez l&rsquo;option <code>--overwrite</code>, soit vous veillez à le supprimer avant.</div>

<h2 id="configuration">Configuration</h2>
<p>Modifions la configuration de nginx, afin de lui signifier que quand il
est demandé des images au format jpeg|gif|png|tiff, il essaye de diffuser
celles au format AVIF, si elles existent.</p>
<hr>
<p>⇒ Dans le contexte <code>http</code> du serveur :</p>
<ol>
<li>dans le fichier <code>/etc/nginx/mime.types</code>, ajoutons la déclaration <code>image/avif                      avif;</code></li>
<li>puis, une <code>map</code> afin de déclarer une variable <code>$avif_suffix</code> qui nous
permettra de reconnaître une image ayant l&rsquo;extension <code>.avif</code>.</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_accept</span> <span style="color:#ef6155">$avif_suffix</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">avif_suffix</span> <span style="color:#48b685">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&#34;~*avif&#34;</span> <span style="color:#48b685">&#34;.avif&#34;</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><hr>
<p>⇒ Modifions le contexte <code>server</code>, <em>préalablement <a class="inside" href="/fr/web/nginx/nginx-image-webp/#configuration" title="Lien interne vers l&#39;article : 'Nginx gère les images au format Webp'">modifié pour le support webp</a>
</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.(jpe?g|gif|png|tiff)$</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">access_log</span>        <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Cache-Control</span> <span style="color:#48b685">&#34;public,</span> <span style="color:#48b685">must-revalidate,</span> <span style="color:#48b685">proxy-revalidate&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Pragma</span> <span style="color:#48b685">public</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">expires</span>           <span style="color:#48b685">max</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">log_not_found</span> <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">try_files</span> <span style="color:#ef6155">$uri$avif_suffix</span> <span style="color:#ef6155">$uri$webp_suffix</span> <span style="color:#ef6155">$uri</span> =<span style="color:#f99b15">404</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Et ajoutons lui ce nouveau bloc <code>location</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.(gif|jpe?g|png|tiff).avif</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">access_log</span>        <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Cache-Control</span> <span style="color:#48b685">&#34;public,</span> <span style="color:#48b685">must-revalidate,</span> <span style="color:#48b685">proxy-revalidate,</span> <span style="color:#48b685">max-age=31536000&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Content-Type</span> <span style="color:#48b685">image/avif</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Pragma</span> <span style="color:#48b685">public</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">image/avif</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">expires</span>           <span style="color:#48b685">max</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#    try_files $uri$avif_suffix $uri =404;
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">types</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">image/avif</span> <span style="color:#48b685">avif</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><hr>
<p>Et, voilà !!!</p>
<p>Reste plus qu&rsquo;à tester votre configuration avec nginx et redémarrer le service
correspondant - <em>par exemple, pour OpenBSD</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# nginx -t
</span></span><span style="display:flex;"><span>:# rcctl restart nginx
</span></span></code></pre></div><h2 id="html">HTML</h2>
<p>Pour finir, modifiez votre code HTML à-propos de la gestion des images,
tel que, par exemple pour une image jpeg, à minima :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">picture</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">source</span> <span style="color:#06b6ef">srcset</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/img/{{ $img }}.jpg.avif&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/avif&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">source</span> <span style="color:#06b6ef">srcset</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/img/{{ $img }}.jpg.webp&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/webp&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">img</span> <span style="color:#06b6ef">alt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;texte&#34;</span> <span style="color:#06b6ef">src</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/img/{{ $img }}.jpg&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/jpeg&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">picture</span>&gt;
</span></span></code></pre></div><p>Ce qui permettra aux clients web qui supportent le format AVIF de demander
l&rsquo;affichage de ce format en lieu et place…</p>
<h3 id="essai">Essai</h3>
<p>Test avec mon Logo :</p>
<figure>
    <a href="/images/logo.png" title="Logo">
    <picture>
        
        <source srcset="/images/logo_hu_c9e055de1824af3f.webp" type="image/webp">
        
        <img alt="Logo" height="128" loading="lazy" src="/images/logo.png" type="image/png" width="128">
    </picture>
    </a>
    <figcaption>Logo</figcaption>
</figure>
<p>Ainsi, selon le support du client web, vous recevrez soit le format webp,
soit avif, sinon le fichier &ldquo;source&rdquo; png…</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>le site caniuse.com: <a href="https://caniuse.com/avif" rel="external">https://caniuse.com/avif</a></li>
<li>l&rsquo;article &ldquo;<a href="https://pawelgrzybek.com/webp-and-avif-images-on-a-hugo-website/" rel="external">WebP and AVIF images on a Hugo website</a>&quot;… <em>en anglais</em></li>
<li>l&rsquo;article &ldquo;<a href="https://blog.uidrafter.com/engineering/convert-to-avif-programmatically" rel="external">Convert to AVIF Programmatically</a>&rdquo; -
<em>en anglais</em> -
qui expliquent les raisons pour lesquelles utiliser un taux de compression
min à 25, max à 35, et recommande la vitesse d&rsquo;encodage sur 0 !</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<p>@Lord et son <a href="https://lord.re/fast-posts/55-un-peu-plus-de-compression-sur-le-brog-brotli+avif/" rel="external">article</a>
qui m&rsquo;a fait découvrir ce format d&rsquo;image…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Configurer Nginx pour qu&#39;il diffuse les images au format AVIF, au lieu de…]]></summary>
        <published>2021-02-22T14:17:28+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:23ae0ec7-964f-d720-fd6f-aeca6f3bac5c</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vmd-console-serie/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [OpenBSD :: Virtualisation] Pas d&#39;écran de connexion ; pas de login !</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="vmd" scheme="http://doc.huc.fr.eu.org/fr/tags/vmd/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Pour rappel, l&rsquo;hyperviseur <a href="https://man.openbsd.org/vmm" rel="external">vmm(4)</a> sous OpenBSD
n&rsquo;a pas de support vidéo pour les VM invités. <strong>Seule la console série est prise en charge</strong>.</p>
<p>Quand vous faites de la virtualisation sous OpenBSD amd64 ou i386, OpenBSD
gère tout ce qu&rsquo;il faut, comme de nécessaire. Ainsi la console série est
configurée au sein du fichier de configuration <code>/etc/boot.conf</code> et le dispositif
<code>tty00</code> est configuré correctement pour utiliser ladite console série.</p>
<hr>
<p>Le problème est quand vous avez l&rsquo;idée de créer votre VM, sous Linux par
exemple, à moins de spécifiquement répondre <code>yes</code> lorsqu&rsquo;est demandé le
paramétrage de <code>com0</code>, il est possible de se retrouver avec le problème
suivant :</p>
<p><strong>Pas d&rsquo;écran de connexion == pas de login possible</strong> !</p>
<p><em>(où il y en a des malchanceux, et d&rsquo;autres où ça roule sans soucis… je suis
souvent de la première catégorie)</em></p>
<hr>
<p>Pour illustrer le propos, une fois la VM OpenBSD copiée sur un hôte OpenBSD,
voici le démarrage :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ vmctl start -c vm-test
</span></span><span style="display:flex;"><span>Using drive 0, partition 3.
</span></span><span style="display:flex;"><span>Loading......
</span></span><span style="display:flex;"><span>probing: pc0 com0 mem<span style="color:#5bc4bf">[</span>638K 1022M <span style="color:#ef6155">a20</span><span style="color:#5bc4bf">=</span>on<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>disk: hd0+
</span></span><span style="display:flex;"><span>&gt;&gt; OpenBSD/amd64 BOOT 3.52
</span></span><span style="display:flex;"><span>boot&gt;
</span></span><span style="display:flex;"><span>booting hd0a:/bsd: 14329128+3191816+337072+0+872448 <span style="color:#5bc4bf">[</span>999468+128+1135344+859361<span style="color:#5bc4bf">]=</span>0x14ba488
</span></span><span style="display:flex;"><span>entry point at 0xffffffff81001000
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> using <span style="color:#f99b15">2995336</span> bytes of bsd ELF symbol table <span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1982, 1986, 1989, 1991, <span style="color:#f99b15">1993</span>
</span></span><span style="display:flex;"><span>    The Regents of the University of California.  All rights reserved.
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1995-2020 OpenBSD. All rights reserved.  https://www.OpenBSD.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OpenBSD 6.8 <span style="color:#5bc4bf">(</span>GENERIC<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#4: Mon Jan 11 10:34:36 MST 2021</span>
</span></span><span style="display:flex;"><span>    root@syspatch-68-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1056956416</span> <span style="color:#5bc4bf">(</span>1007MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1010040832</span> <span style="color:#5bc4bf">(</span>963MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>random: good seed from bootblocks
</span></span><span style="display:flex;"><span>mpath0 at root
</span></span><span style="display:flex;"><span>scsibus0 at mpath0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>mainbus0 at root
</span></span><span style="display:flex;"><span>bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf3f40 <span style="color:#5bc4bf">(</span><span style="color:#f99b15">10</span> entries<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>bios0: vendor SeaBIOS version <span style="color:#48b685">&#34;1.11.0p3-OpenBSD-vmm&#34;</span> date 01/01/2011
</span></span><span style="display:flex;"><span>bios0: OpenBSD VMM
</span></span><span style="display:flex;"><span>acpi at bios0 not configured
</span></span><span style="display:flex;"><span>cpu0 at mainbus0: <span style="color:#5bc4bf">(</span>uniprocessor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu0: AMD FX-8320E Eight-Core Processor, 3211.59 MHz, 15-02-00
</span></span><span style="display:flex;"><span>cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,CX8,SEP,PGE,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,PCLMUL,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,POPCNT,AES,XSAVE,AVX,F16C,HV,NXE,MMXX,FFXSR,PAGE1GB,LONG,LAHF,CMPLEG,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,XOP,SKINIT,WDT,FMA4,TCE,NODEID,TBM,TOPEXT,CPCTR,ITSC,BMI1
</span></span><span style="display:flex;"><span>cpu0: 64KB 64b/line 2-way I-cache, 16KB 64b/line 4-way D-cache, 2MB 64b/line 16-way L2 cache, 8MB 64b/line 64-way L3 cache
</span></span><span style="display:flex;"><span>cpu0: ITLB <span style="color:#f99b15">48</span> 4KB entries fully associative, <span style="color:#f99b15">24</span> 4MB entries fully associative
</span></span><span style="display:flex;"><span>cpu0: DTLB <span style="color:#f99b15">64</span> 4KB entries fully associative, <span style="color:#f99b15">64</span> 4MB entries fully associative
</span></span><span style="display:flex;"><span>cpu0: smt 0, core 0, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pvbus0 at mainbus0: OpenBSD
</span></span><span style="display:flex;"><span>pvclock0 at pvbus0
</span></span><span style="display:flex;"><span>pci0 at mainbus0 bus <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pchb0 at pci0 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;OpenBSD VMM Host&#34;</span> rev 0x00
</span></span><span style="display:flex;"><span>virtio0 at pci0 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Qumranet Virtio RNG&#34;</span> rev 0x00
</span></span><span style="display:flex;"><span>viornd0 at virtio0
</span></span><span style="display:flex;"><span>virtio0: irq <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>virtio1 at pci0 dev <span style="color:#f99b15">2</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Qumranet Virtio Network&#34;</span> rev 0x00
</span></span><span style="display:flex;"><span>vio0 at virtio1: address fe:e1:bb:d1:a9:7b
</span></span><span style="display:flex;"><span>virtio1: irq <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>virtio2 at pci0 dev <span style="color:#f99b15">3</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Qumranet Virtio Storage&#34;</span> rev 0x00
</span></span><span style="display:flex;"><span>vioblk0 at virtio2
</span></span><span style="display:flex;"><span>scsibus1 at vioblk0: <span style="color:#f99b15">1</span> targets
</span></span><span style="display:flex;"><span>sd0 at scsibus1 targ <span style="color:#f99b15">0</span> lun 0: &lt;VirtIO, Block Device, &gt;
</span></span><span style="display:flex;"><span>sd0: 51200MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">104857600</span> sectors
</span></span><span style="display:flex;"><span>virtio2: irq <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>virtio3 at pci0 dev <span style="color:#f99b15">4</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;OpenBSD VMM Control&#34;</span> rev 0x00
</span></span><span style="display:flex;"><span>vmmci0 at virtio3
</span></span><span style="display:flex;"><span>virtio3: irq <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>isa0 at mainbus0
</span></span><span style="display:flex;"><span>isadma0 at isa0
</span></span><span style="display:flex;"><span>com0 at isa0 port 0x3f8/8 irq 4: ns8250, no fifo
</span></span><span style="display:flex;"><span>com0: console
</span></span><span style="display:flex;"><span>vscsi0 at root
</span></span><span style="display:flex;"><span>scsibus2 at vscsi0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>softraid0 at root
</span></span><span style="display:flex;"><span>scsibus3 at softraid0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>root on sd0a <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.a<span style="color:#5bc4bf">)</span> swap on sd0b dump on sd0b
</span></span><span style="display:flex;"><span>Automatic boot in progress: starting file system checks.
</span></span><span style="display:flex;"><span>/dev/sd0a <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.a<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0m <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.m<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0d <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.d<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0f <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.f<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0g <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.g<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0h <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.h<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0j <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.j<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0i <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.i<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0e <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.e<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0k <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.k<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>/dev/sd0l <span style="color:#5bc4bf">(</span>6dc570f70e2c7991.l<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>pf enabled
</span></span><span style="display:flex;"><span>kern.seminfo.semmni: <span style="color:#f99b15">10</span> -&gt; <span style="color:#f99b15">60</span>
</span></span><span style="display:flex;"><span>kern.seminfo.semmns: <span style="color:#f99b15">60</span> -&gt; <span style="color:#f99b15">1024</span>
</span></span><span style="display:flex;"><span>starting network
</span></span><span style="display:flex;"><span>reordering libraries: <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>starting early daemons: syslogd pflogd nsd ntpd.
</span></span><span style="display:flex;"><span>starting RPC daemons:.
</span></span><span style="display:flex;"><span>savecore: no core dump
</span></span><span style="display:flex;"><span>checking quotas: <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>clearing /tmp
</span></span><span style="display:flex;"><span>kern.securelevel: <span style="color:#f99b15">0</span> -&gt; <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>creating runtime link editor directory cache.
</span></span><span style="display:flex;"><span>preserving editor files.
</span></span><span style="display:flex;"><span>starting network daemons: sshd smtpd.
</span></span><span style="display:flex;"><span>starting local daemons: cron.
</span></span><span style="display:flex;"><span>Thu Feb <span style="color:#f99b15">18</span> 12:25:45 CET <span style="color:#f99b15">2021</span>
</span></span></code></pre></div><p>Et, voilà cela s&rsquo;arrête à l&rsquo;affichage de l&rsquo;heure… et vous allez pouvoir
attendre longtemps l&rsquo;écran de connexion de session qui ne viendra jamais !</p>
<hr>
<p>Et, au cas où tu te le demandes, toi lecteur, non cela ne vient pas d&rsquo;une
corruption de la VM lors de la copie/synchronisation, des tests à base de
somme de contrôle sha256 ont été faits avant la copie et après celle-ci,
tel que :</p>
<p>Sur la station Linux :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ cat vm-test.qcow2.sha256
</span></span><span style="display:flex;"><span>73054a89bb2e0b13d78e8cb446424baa01f7761099d8681a59137655b28c979c  vm-test.qcow2
</span></span></code></pre></div><p>Puis sur l&rsquo;hôte OpenBSD :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ sha256 vm-test.qcow2                                                                                                                                                                    
</span></span><span style="display:flex;"><span>SHA256 <span style="color:#5bc4bf">(</span>vm-test.qcow2<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">=</span> 73054a89bb2e0b13d78e8cb446424baa01f7761099d8681a59137655b28c979c
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ sha256 -C vm-test.qcow2.sha256 vm-test.qcow2
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>SHA256<span style="color:#5bc4bf">)</span> vm-test.qcow2: OK
</span></span></code></pre></div><hr>
<p>Mais alors que faire ?!</p>
<p>Sur ton OS source, par exemple le Linux où la VM a été créée, avec <strong>qemu</strong>
et les différents outils <strong>virt*</strong>, connectes-toi à ta VM, et fais les deux petites
modifications suivantes nécessaires :</p>
<h2 id="configuration">Configuration</h2>
<h3 id="bootconf">boot.conf</h3>
<p>Le fichier de configuration <code>/etc/boot.conf</code> n&rsquo;a pas été créé - <em>s&rsquo;il l&rsquo;est,
vérifies l&rsquo;écriture</em>. Il doit absolument contenir à minima ceci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">set tty com0</span>
</span></span></code></pre></div><p>Par défaut, le taux de connexion est ainsi de 9200 baups.</p>
<hr>
<p>Or, étant donné que le futur hôte est OpenBSD, faisons ça bien :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">stty com0 115200</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set tty com0</span>
</span></span></code></pre></div><p>Ainsi nous configurons le taux de débit au maximum supporté, soit de 115200.</p>
<h3 id="ttys">ttys</h3>
<p>L&rsquo;autre modification nécessaire à faire est de reparamétrer les informations
d&rsquo;initialisation du Terminal <strong>tty00</strong>.</p>
<p>Le fichier est <code>/etc/ttys</code>, et il faut commenter/supprimer la ligne correspondante
à <strong>tty00</strong> pour ajouter la déclaration correcte suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">tty00   &#34;/usr/libexec/getty std.115200&#34; vt220    on secure</span>
</span></span></code></pre></div><p>Si vous déclarez le fichier <code>boot.conf</code> ci-dessus a sa valeur par défaut,
configurez cette déclaration ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">tty00   &#34;/usr/libexec/getty std.9600&#34;   vt220   on secure</span>
</span></span></code></pre></div><hr>
<p>Et, voilà !</p>
<p>Une fois la VM recopiée sous OpenBSD, vous aurez à nouveau l&rsquo;écran de connexion.</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>la FAQ Officielle d&rsquo;OpenBSD &ldquo;<a href="https://www.openbsd.org/faq/faq7.html#SerCon" rel="external">Configuring a Serial Console</a>&rdquo;
<em>(cf : la traduction <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/faq7#configurer-une-console-serie" rel="external">FR</a> faite par la communauté &ldquo;OpenBSD Pour Tous&rdquo;)</em></li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<p>@<a href="http://daemonforums.org/showthread.php?t=11643" rel="external">jggimi</a>…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre le problème de console série pour une VM, copiée depuis un autre OS vers OpenBSD !]]></summary>
        <published>2021-02-21T23:14:42+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1e91be69-17c6-eeb8-75a3-c8c7e7367eea</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vmd-hote-invite-meme-reseau/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [OpenBSD :: Virtualisation] Hôte et invité(s) sont sur le même bateau</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="vmd" scheme="http://doc.huc.fr.eu.org/fr/tags/vmd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La virtualisation sous OpenBSD, disponible depuis 5.9, est assez aisée à
mettre en place, à partir du moment où on fait attention à certains détails.</p>
<p>Cet article traite de la partie de la virtualisation où hôte et invité(s)
sont sur le même réseau, et offrira en sus ce que ne restitue pas la <a href="https://www.openbsd.org/faq/faq16.html" rel="external">FAQ
officielle</a> <em>(ou sa traduction [FR][2])</em>.</p>
<ul>
<li>Version : <strong>native</strong></li>
<li>OS : OpenBSD <strong>6.4</strong> → <strong>7.2</strong></li>
</ul>
<h2 id="pré-requis">Pré-requis</h2>
<p>En premier, toujours vérifier et s&rsquo;assurer de la compatibilité du processeur
de votre machine :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ dmesg | egrep <span style="color:#48b685">&#39;(VMX/EPT|SVM/RVI)&#39;</span>
</span></span></code></pre></div><p>La réponse du système doit être :</p>
<p>⇒ pour CPU Intel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT
</span></span></code></pre></div><p>⇒ pour CPU AMD :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: SVM/RVI
</span></span></code></pre></div><p>Si aucune ligne n&rsquo;apparaît, aucune virtualisation ne sera possible. Par
acquis de conscience, vérifiez votre BIOS|UEFI que celle-ci ne soit pas
désactivée.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>De même, en rapport avec les failles CPU relatives à Meltdown, Spectre,
certains CPU Intel sont patchés pour remédier à
<a href="https://www.intel.fr/content/www/fr/fr/architecture-and-technology/l1tf.html" rel="external">L1TF</a>.
Sous OpenBSD, ces CPU reçoivent un correctif approprié. Malheureusement,
cela impacte la virtualisation et peut rendre celle-ci impossible.
Vous pouvez vous retrouver dans la situation où vous auriez un CPU
compatible, mais dans les faits, la virtualisation ne pourrait être
pleinement fonctionnelle.</p>
<p><em>Préférez AMD, en attendant ARM…</em></p>
</div>

<h2 id="création">Création</h2>
<p>Après avoir téléchargé l&rsquo;image <code>instalXX.iso</code> de la dernière version d&rsquo;OpenBSD
puis l&rsquo;avoir vérifié  - <em>oui, préférez l&rsquo;image iso, et lors de l&rsquo;installation,
choisissez <code>cd0</code> au lieu de <code>http</code>, elle se fera plus vite car ira chercher
les jeux d&rsquo;installation sur votre média</em>.</p>
<p>⇒ Créons simplement une VM :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ vmctl create -s 50G disk.qcow2
</span></span></code></pre></div><p>⇒ Démarrons l&rsquo;installation :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># vmctl start -c -m 1G -i 1 -r installXX.iso -d disk.qcow2 test</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est important de déclarer une interface réseau, au moins avec l&rsquo;option
<code>-i</code> lors de cette étape. Cela va permettre d&rsquo;allouer automatiquement une
interface <strong><a href="https://man.openbsd.org/tap.4" rel="external">tap(4)</a></strong> à la VM.</p>
<p>Pour la virtualisation de VM sur le même réseau que l&rsquo;hôte, <strong>n&rsquo;utilisez pas
l&rsquo;option <code>-L</code></strong> qui déclare une interface locale, empêchant de communiquer
avec le bridge. <em>Il faudrait dans ce cas-là, faire de la traduction d&rsquo;adresses
réseaux, configurer sysctl, etc. - Avouez, ce serait dommage.</em></p>
</div>

<p>Faites votre installation, et au bout de quelques minutes, à la fin de
celle-ci choisissez <code>[halt]</code> pour arrêter proprement l&rsquo;OS dans la VM.</p>
<p>Puis déconnectez-vous de celle-ci, par exemple par les caractères d&rsquo;échappement
<code>~.</code> ou <code>~~.</code> si SSH.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Une autre raison pour laquelle il vaut mieux arrêter la VM : si vous ne
le faites pas, vous allez redémarrer celle-ci sans soucis… mais vous n&rsquo;aurez
pas de réseau ; ne cherchez pas à à modifier vos paramètres réseaux,
vous pouvez quand même vérifier l&rsquo;adresse IP de votre passerelle/routeur,
ainsi que résolveur DNS que vous avez paramétré.</p>
<p>L&rsquo;astuce est simplement de configurer le fichier <code>/etc/vm.conf</code> de l&rsquo;hôte,
puis de (re)démarrer le service vmd, et ensuite de redémarrer la VM.
Normalement, là, vous devriez avoir du réseau… dans votre VM.</p>
</div>

<h2 id="configuration">Configuration</h2>
<p>En admettant que :</p>
<ul>
<li>le réseau est de type de Classe C : 192.168.1.0</li>
<li>l&rsquo;adresse IP de la passerelle serait : 192.168.1.1</li>
<li>les <a href="https://www.fdn.fr/actions/dns/" rel="external">résolveurs DNS</a> seraient ceux de la FDN…</li>
</ul>
<p>Ce sont les paramètres réseaux à fournir dans les VM.</p>
<hr>
<p>Les configurations suivantes se font sur l&rsquo;hôte :</p>
<h3 id="réseau">Réseau</h3>
<p><strong>Seuls les périphériques Ethernet, non Wifi, peuvent être utilisés</strong>.</p>
<p>Utilisez dhcp peut compliquer les choses, préférez l&rsquo;usage d&rsquo;adresse IP
statique.</p>
<h3 id="hostnameiface">hostname.iface</h3>
<p>Partons du contexte où votre interface réseau est gérée par le pilote réseau
Intel <strong><a href="https://man.openbsd.org/man4/em.4" rel="external">em(4)</a></strong>.</p>
<p><em>Si ce n&rsquo;est pas votre cas, modifiez en conséquence.</em></p>
<p>Modifions le fichier <code>/etc/hostname.em0</code>, pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">inet 192.168.1.2</span>
</span></span></code></pre></div><h3 id="vmconf">vm.conf</h3>
<p>Le fichier de configuration est : <code>/etc/vm.conf</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">switch &#34;sw&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">interface bridge0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">vm &#34;test&#34; {    </span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">disk /home/vous/disk.qcow2 format qcow2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">enable</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">memory 1G</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">interface { switch &#34;sw&#34; }</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">owner vous</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><h3 id="bridge">Bridge</h3>
<p>Configurons le pont :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># echo &#39;add em0&#39; &gt; /etc/hostname.bridge0</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sh /etc/netstart bridge0</span>
</span></span></code></pre></div><p>Et, voilà !</p>
<hr>
<p>Sauf que… ce dont ne parle pas la FAQ, a un rapport étroit avec PF, principalement.</p>
<p>Autre information importante que ne restitue pas la FAQ est que lorsque
la VM est active, une interface tap est créée et montée dans le bridge.
Du moins, c&rsquo;est compréhensible au-travers de la lecture des différents manpages.</p>
<h3 id="pf">PF</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">N&rsquo;utilisez pas <a href="https://www.openbsd.org/faq/pf/filter.html#urpf" rel="external">uRPF</a>
avec vm, autrement vous ne pourriez plus communiquer depuis vos VM avec
l&rsquo;extérieur et réciproquement !</div>

<p>Selon les <a href="https://man.openbsd.org/bridge.4#NOTES" rel="external">notes du manpage relatif à bridge</a>,
paramétrer PF pour gérer le bridge est possible, mais il faut être très
fin dans ces réglages et avoir une excellente compréhension du flux réseau
au sein de PF.</p>
<p>Faisons au plus simple, sur le fichier de configuration de PF de l&rsquo;hôte :</p>
<p>⇒ Gérons le groupe d&rsquo;interface <strong>tap</strong> en autorisant tout le flux :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass on tap</span>
</span></span></code></pre></div><p>L&rsquo;avantage de gérer le groupe <strong>tap</strong> est de ne pas avoir à gérer finement
toutes les interfaces tap liées à chacune des VM. En effet, chaque VM aura
sa propre interface tap. La première aura l&rsquo;interface <strong>tap0</strong>, la seconde
aura <strong>tap1</strong>, etc.</p>
<p>Dans ces cas, il faudrait déclarer pour chaque interface, par exemple
pour tap0 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass on tap0</span>
</span></span></code></pre></div><p>⇒ Ensuite, il faut gérer d&rsquo;abord votre interface réseau, qui pour l&rsquo;exemple
est <strong>em0</strong>, au cas par cas selon le flux que vous désirez permettre en
entrée depuis l&rsquo;hôte vers l&rsquo;IP de la VM.</p>
<hr>
<p>Là encore, pour simplifier, déclarer une table comprenant l&rsquo;adresse IP
de chaque VM, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;vm_tap&gt; const { 192.168.1.3 192.168.1.4 }</span>
</span></span></code></pre></div><p>Puis par exemple pour autoriser le flux à destination de SSH vers les VM :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass in log on em0 inet proto tcp from any to &lt;vm_tab&gt; port 22 </span>
</span></span></code></pre></div><p>Bien sûr, ces règles PF sont minimalistes, en soit. À vous de les granuler
plus finement, selon vos besoins et selon les services à accéder.</p>
<p>Pour finir, pensez à gérer vos règles PF au sein de la VM, elle-même. ;-)</p>
<h3 id="pseudo-dispositif-virtuel-tap">Pseudo-dispositif virtuel tap</h3>
<p>Par défaut, OpenBSD fournit 4 pseudo-interfaces virtuelles tap. En cas,
où vous nécessitez de plus de VM que ces 4 disponibles par défaut, il
est nécessaire de créer le nombre d&rsquo;interface supplémentaire.</p>
<p><em>Lire la <a href="https://man.openbsd.org/vm.conf.5#SWITCH_CONFIGURATION" rel="external">note suivante</a>…
pour bien comprendre l&rsquo;allocation automatique des interfaces virtuelles.</em></p>
<p>Il faudra utiliser <a href="https://man.openbsd.org/MAKEDEV.8" rel="external">MAKEDEV(8)</a>, par
exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># sh MAKEDEV tap5</span>
</span></span></code></pre></div><p>De même, il est possible d&rsquo;assigner tel pseudo-dispositif virtuel tap, à
telle VM, utilisez pour cela le mot clé <strong><a href="https://man.openbsd.org/vm.conf.5#interface" rel="external">interface</a></strong>
dans votre fichier de configuration, tel que par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">vm &#34;test&#34; { </span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">interface tap5 { … }</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Autre point à bien comprendre est que tant que la VM n&rsquo;est pas active,
l&rsquo;interface tap correspondante ne sera pas créée ni montée au sein du
bridge. Faites la comparaison avec la commande <code>ifconfig</code> avant puis
après… et vous comprendrez ;-)</p>
<h3 id="sysctl">sysctl</h3>
<p>Non, il n&rsquo;y a pas besoin de configurer sysctl pour rediriger <em>(forward)</em> le flux.
Nous ne faisons pas de la traduction d&rsquo;adresses réseaux, autrement appelée
NAT. Ce serait le cas et le besoin dans le contexte de bridge où les VM
auraient leur propre réseau différent de celui de l&rsquo;hôte.</p>
<p>Le rappel est fait dans la section suivante de la page de manuel <strong><a href="https://man.openbsd.org/vmctl.8#LOCAL_INTERFACES" rel="external">vmctl</a></strong> :</p>
<blockquote>
<p>If NAT is desired, the net.inet.ip.forwarding sysctl(8) must also be set to 1.</p>
</blockquote>
<p>Donc, non, dans le contexte de bridge où l&rsquo;hôte et les invités sont sur
le même bateau, pas besoin de forwarder le flux !</p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li>
<p>Merci de lire la documentation officielle <strong>FAQ Virtualisation</strong> (<a href="https://www.openbsd.org/faq/faq16.html" rel="external">EN</a>)
afin de bien comprendre le sujet, les différentes informations nécessaires
à une meilleure préhension de celui-ci.</p>
</li>
<li>
<p>Il est fortement intéressant de lire les pages de manuels, en anglais, relative à :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/vmctl.8" title="Page du Manuel OpenBSD pour : vmctl">vmctl(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vmd.8" title="Page du Manuel OpenBSD pour : vmd">vmd(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vm.conf.5" title="Page du Manuel OpenBSD pour : vm.conf">vm.conf(5)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vmm.4" title="Page du Manuel OpenBSD pour : vmm">vmm(4)</a>
</li>
<li>sans oublier 
<a class="man" href="https://man.openbsd.org/bridge.4" title="Page du Manuel OpenBSD pour : bridge">bridge(4)</a>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>Voici un <a href="http://daemonforums.org/showthread.php?t=11628" rel="external">exemple</a> - <em>en anglais</em> -
de CPU Intel patché L1TF où le média de démarrage n&rsquo;était pas trouvé, avec
message d&rsquo;erreur dans <code>dmesg</code> :  <br>
<code>vmx_fault_page: uvm_fault returns 14, GPA=0xffffca78, rip=0xfbd49</code></li>
</ul>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour virtualiser sereinement sous OpenBSD grâce à vmd, où l&#39;hôte et le(s) invité(s) font partie du même réseau !]]></summary>
        <published>2021-02-21T19:54:31+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b7e4d502-ea2d-452c-f63a-48a8b27d9aab</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/solene-rapenne/openbsd-default-security/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Quelle sécurité offre par défaut une installation d&#39;OpenBSD ?</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Sécurité" scheme="http://doc.huc.fr.eu.org/fr/tags/s%C3%A9curit%C3%A9/" />
        <category term="6.9" scheme="http://doc.huc.fr.eu.org/fr/tags/6.9/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://dataswamp.org/~solene/2021-02-14-openbsd-default-security.html" rel="external">What security does a default OpenBSD installation offer?</a></strong>&rdquo;,
écrit par Solène Rapenne.</p>
<hr>
<h2 id="introduction">Introduction</h2>
<p>Dans ce texte, j&rsquo;expliquerais ce qui rend OpenBSD sécurisé par défaut quand
vous l&rsquo;installez. Ce n&rsquo;est pas une analyse de la sécurité, mais plutôt un
guide pour vous aider à comprendre ce qui est fait pour qu&rsquo;OpenBSD soit
un environnement sécurisé. Le but est ce texte n&rsquo;est pas de comparer OpenBSD
à d&rsquo;autres OS mais de vous dire ce que vous pouvez attendre honnêtement
d&rsquo;OpenBSD.</p>
<p>Il n&rsquo;y a pas de sécurité sans modèle de gestion des menaces. Je considère
toujours les cas suivants : un ordinateur volé à domicile, une attaque à
distance qui essaye d&rsquo;exploiter les services fonctionnant, un exploit
au-travers des clients réseaux.</p>
<h2 id="gestion-de-la-sécurité">Gestion de la Sécurité</h2>
<p>Voici une liste de fonctionnalités que je considère importante pour la
sécurité du système d&rsquo;exploitation. Bien que tous les éléments de la liste
suivante ne sont pas à strictement parlé des fonctionnalités de sécurité,
ils aident à obtenir un système strict qui empêche le logiciel de mal se
comporter ou les risques inconnus.</p>
<p>Mon opinion relative à la sécurité n&rsquo;est pas seulement de prévenir les
attaques à distances de pénétrer le système, mais aussi d&rsquo;empêcher les
programmes ou les utilisateurs de rendre le système inutilisable.</p>
<h3 id="pledge--unveil-en-espace-utilisateur">Pledge / Unveil en espace utilisateur</h3>
<p>Pledge et unveil sont souvent cités ensembles bien qu&rsquo;ils puissent être
utilisés indépendamment. Pledge est un système d&rsquo;appels pour restreindre
les permissions d&rsquo;un programme au sein de son code source, permissions qui
ne peuvent pas être annulées une fois l&rsquo;appel à pledge. Unveil est un
système d&rsquo;appels qui cache tout le système de fichiers au processus
excepté les chemins qui ne sont pas surveillés ; il est possible de choisir
quelles permissions sont appliquées aux chemins.</p>
<p>Les deux sont de puissants outils de sécurité &ldquo;chirurgicaux&rdquo; mais ils
requièrent quelques modifications dans le code source d&rsquo;un programme, et
les ajouter requiert une profonde compréhension de ce que fait le logiciel.
Il n&rsquo;est pas toujours possible d&rsquo;interdire les appels systèmes d&rsquo;un logiciel
qui exige de faire presque tout ; un logiciel conçu avec la séparation
des privilèges est un meilleur candidat pour l&rsquo;ajout propre de pledge, ainsi
chaque partie fait son travail.</p>
<p>Certains logiciels parmi les paquets prennent en charge pledge et/ou unveil,
tel que Chromium ou Firefox, pour les plus connus.</p>
<ul>
<li><a href="https://www.openbsd.org/papers/bsdcan2019-unveil/index.html" rel="external">OpenBSD presentation about Unveil (BSDCan2019)</a></li>
<li><a href="https://www.openbsd.org/papers/BeckPledgeUnveilBSDCan2018.pdf" rel="external">OpenBSD presentation of Pledge and Unveil (BSDCan2018)</a></li>
</ul>
<h3 id="séparation-des-privilèges">Séparation des privilèges</h3>
<p>La plupart des services du système de base d&rsquo;OpenBSD fonctionnent selon
le modèle de séparation des privilèges. Chaque part d&rsquo;un démon est restreint
au minimum requis. Un démon monolithique devrait lire, écrire des fichiers,
accepter des connexions réseaux, envoyer des messages au système de journalisation,
dans le cas d&rsquo;une brèche de sécurité qui offre une énorme surface d&rsquo;attaque.
En séparant un service en de multiples parties, cela permet un contrôle
plus fin de chacun des processus, et en utilisant les appels systèmes de pledge
et unveil, il est possible de paramétrer les limites et de réduire hautement
les dommages en cas où un processus est attaqué.</p>
<h3 id="synchronisation-de-lhorloge">Synchronisation de l&rsquo;Horloge</h3>
<p>Le démon du serveur est démarré par défaut afin de synchroniser l&rsquo;horloge
avec des serveurs de temps. Un serveur TLS référant est utilisé pour
interroger les serveurs de temps. Garder un ordinateur avec son horloge
synchronisée est très important. Ce n&rsquo;est pas réellement une fonctionnalité
de sécurité mais vous ne pouvez pas être sérieux si vous utilisez un
ordinateur sur le réseau qui n&rsquo;ait pas son temps synchronisé.</p>
<h3 id="affichage-x-sans-droits-root">Affichage X sans droits root</h3>
<p>si vous utilisez le serveur X, il abandonne les privilèges à l&rsquo;utilisateur
<code>_x11</code> ; le serveur est exécuté avec les droits d&rsquo;un utilisateur
sans privilèges au lieu de root, ainsi en cas de problèmes de sécurité
cela empêche un attaquant d’accéder au-travers de bogues de X11 à plus
qu&rsquo;il ne devrait.</p>
<h3 id="ressources-limitées">Ressources limitées</h3>
<p>Les limites de ressources par défaut empêchent un programme d&rsquo;utiliser
trop de mémoire, d&rsquo;ouvrir trop de fichier ou trop de processus. Bien que
cela puisse empêcher que certains gros programmes de s&rsquo;exécuter avec les
paramètres par défaut, cela aide aussi à trouver les failles de descripteurs
de fichiers, prévenant ainsi une bombe dérivée ou un simple démon de
capturer toute la mémoire jusqu&rsquo;au crash.</p>
<h3 id="authentique-chiffrement-de-disque">Authentique chiffrement de disque</h3>
<p>Quand vous installez OpenBSD selon le mode de chiffrement complet de disque,
tout sera verrouillé par une passphrase à l&rsquo;étape du chargeur de démarrage,
ainsi vous ne pouvez accéder au noyau ou à d&rsquo;autres parties du système sans
la passphrase.</p>
<h3 id="wx">W^X</h3>
<p>La plupart des programmes dans OpenBSD n&rsquo;ont pas l&rsquo;autorisation de cartographier
la mémoire avec un bit d&rsquo;Exécution et d’Écriture en même temps (W^X signifie
Écrire et/ou Exécuter), cela peut empêcher un interpréteur d&rsquo;avoir sa mémoire
et modifiée et exécutée. Certains paquets ne sont pas conformes à cela et
doivent être liés à une bibliothèque spécifique qui contourne cette
restriction ET doivent être utilisés depuis une partition ayant l&rsquo;option
de montage &ldquo;wxallowed&rdquo;.</p>
<ul>
<li><a href="https://www.openbsd.org/papers/hackfest2015-w-xor-x.pdf" rel="external">OpenBSD presentation « Kernel W^X Improvements In OpenBSD »</a></li>
</ul>
<h3 id="une-seule-source-fiable-de-données-aléatoires">Une seule source fiable de données aléatoires</h3>
<p>Lorsque votre système requiert un nombre de données aléatoires (et c&rsquo;est
souvent le cas), OpenBSD fournit seulement une seule API pour obtenir ces
données aléatoires, qui sont réellement aléatoires et ne peuvent être devinées.
Un bon générateur de nombres aléatoires (RNG) est important pour de nombreuses
exigences en matière de cryptographie.</p>
<ul>
<li><a href="https://www.openbsd.org/papers/hackfest2014-arc4random/index.html" rel="external">OpenBSD presentation about arc4random</a></li>
</ul>
<h3 id="une-documentation-précise">Une documentation précise</h3>
<p>OpenBSD est fournit avec une documentation complète dans ses pages de manuels.
On doit pouvoir configurer entièrement son système en utilisant seulement
les pages de manuels. Les pages de manuels sont fournis parfois avec des
sections CAVEATS ou BUGS ; il est important de bien faire attention à ces
sections. Il est mieux de lire la documentation et de comprendre ce que
cela fait avant de configurer un système au lieu de suivre un anonyme texte
obsolète disponible sur Internet.</p>
<ul>
<li><a href="https://man.openbsd.org/" rel="external">OpenBSD man pages online</a></li>
<li><a href="https://www.openbsd.org/papers/eurobsdcon2018-mandoc.pdf" rel="external">EuroBSDcon 2018 about « Better documentation »</a></li>
</ul>
<h3 id="ipsec-et-wireguard-à-lintérieur">IPSec et Wireguard à l&rsquo;intérieur</h3>
<p>Si vous avez besoin de paramétrer un VPN, vous pouvez utiliser nativement
les protocoles IPSec ou Wireguard, sans aucun autre paquet requis.</p>
<h3 id="sécurité-de-la-mémoire">Sécurité de la mémoire</h3>
<p>OpenBSD a de nombreuses mesures de sécurités à-propos de l&rsquo;allocation de
la mémoire et empêchera son utilisation après libération ou un usage très
agressif de mémoire non sûre, souvent sources de crash pour certains logiciels
fournis en tant que paquets puisqu&rsquo;OpenBSD est très strict sur l&rsquo;utilisation
de la mémoire que vous faites. Cela aide à trouver les utilisations abusives
de la mémoire et à arrêter les mauvais comportements logiciels.</p>
<h3 id="compte-root-dédié">Compte root dédié</h3>
<p>Lorsque vous installez le système, un compte root est créé et son mot de
passe est demandé, puis vous créez un utilisateur qui sera membre du groupe
&ldquo;wheel&rdquo;, permettant de basculer l&rsquo;utilisateur vers root avec le mot de
passe de root. doas (l&rsquo;équivalent sudo d&rsquo;OpenBSD) n&rsquo;est pas configuré par
défaut. Avec l&rsquo;installation par défaut, le mot de passe root est requis
pour toute interaction root. Je pense qu&rsquo;un compte root dédié qui peut
être journalisé sans l&rsquo;usage de doas ou sudo est mieux qu&rsquo;une mauvaise
configuration de doas ou sudo permettant ainsi de faire des choses seulement
si vous connaissez le mot de passe utilisateur.</p>
<h3 id="la-plus-petite-surface-dattaque-réseau">La plus petite surface d&rsquo;attaque réseau</h3>
<p>Les seuls services qui pourraient être activés dès l&rsquo;installation, écoutant
sur le réseau, sont OpenSSH (demandé lors de l&rsquo;installation, avec par défaut
sur yes), dhclient (si vous choisissez dhcp) et slaacd (si vous utilisez
IPv6 en configuration automatique).</p>
<h3 id="swap-chiffrée">Swap chiffrée</h3>
<p>Par défaut, la swap d&rsquo;OpenBSD est chiffrée, ce qui signifie que si la mémoire
des programmes est envoyée vers la swap, nul ne pourra la déchiffrer plus tard.</p>
<h3 id="smt-désactivé">SMT désactivé</h3>
<p>Dû fait d&rsquo;un très grand nombre de failles de sécurité sur SMT (tel que
l&rsquo;HyperThreading), l&rsquo;installation par défaut désactive les cœurs logiciels
afin de prévenir toutes fuites de données.</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)" rel="external">Meltdown: one of the first security issue related to speculative execution in the CPU</a></li>
</ul>
<h3 id="microphone-et-webcam-désactivés">Microphone et Webcam désactivés</h3>
<p>Avec l&rsquo;installation par défaut, les microphones et webcam ne peuvent actuellement
rien enregistrer excepté du bruit blanc à moins que vous configuriez
sysctl pour cela.</p>
<h3 id="maintenance-sorties-et-mises-à-jour-fréquentes">Maintenance, sorties et mises à jour fréquentes</h3>
<p>L&rsquo;équipe d&rsquo;OpenBSD publie une nouvelle version tous les six mois, et seules
les deux dernières versions reçoivent les mises à jours de sécurité.
Cela permet de mettre à jour sans douleur ; le processus de mise à jour
est constitué de petites étapes deux fois par an, ce qui aide à garder
l&rsquo;ensemble du système à jour.
Cela évite la crainte d&rsquo;une mise à jour massive, de ne jamais la faire et
je considère que c&rsquo;est un énorme bonus de sécurité. La plupart des OpenBSD
fonctionnent sur les versions les plus récentes.</p>
<h3 id="signify--chaîne-de-confiance">Signify : chaîne de confiance</h3>
<p>L&rsquo;installateur, les archives et les paquets sont signés en utilisant les
clés publiques et privées de signify. Les installations d&rsquo;OpenBSD sont
fournies avec les versions de clés de la version courante et n+1 afin de
vérifier l’authenticité des paquets. Une clé est utilisée seulement six mois
et de nouvelles clés sont reçues à chaque nouvelle sortie permettant de
construire une chaîne de confiance. Les clés Signify sont très petites et
sont publiées dans de nombreux médias afin de permettre une double vérification
si vous avez besoin de vous assurer de cette chaîne de confiance.</p>
<ul>
<li><a href="https://www.openbsd.org/papers/bsdcan-signify.html" rel="external">Signify at BSDCan 2015</a></li>
</ul>
<h2 id="les-paquets">Les Paquets</h2>
<p>Alors que la plupart des éléments précédents concernaient le système de
base ou le noyau, les paquets ont également quelques astuces à offrir.</p>
<h3 id="chroot-par-défaut-quand-disponible">chroot par défaut quand disponible</h3>
<p>La plupart des démons qui sont disponibles offrent une fonctionnalité de
chroot qui sera activée par défaut. Dans certaines circonstances, tel que
pour le serveur web Nginx, le logiciel est patché par l&rsquo;équipe OpenBSD
afin d&rsquo;activer chroot qui n&rsquo;est pas une fonctionnalité officielle.</p>
<h3 id="des-utilisateurs-dédiés-aux-services">Des utilisateurs dédiés aux services</h3>
<p>La plupart des paquets qui fournissent un serveur crée aussi un utilisateur
dédié exactement à ce service, permettant la séparation des privilèges en
cas de problèmes de sécurité dans le service.</p>
<h3 id="linstallation-dun-service-ne-lactive-pas">L&rsquo;installation d&rsquo;un service ne l&rsquo;active pas</h3>
<p>Lorsque vous installez un service, celui-ci n&rsquo;est pas activé par défaut.
Vous allez devoir configurer le système pour l&rsquo;activer au démarrage.
Il y a un unique fichier <code>/etc/rc.conf.local</code> qui peut être utilisé pour
voir ce qui est actif au démarrage, qui peut être manipulé par l&rsquo;utilisation
de la commande <code>rcctl</code>.
Forcer l&rsquo;utilisateur à activer les services oblige l&rsquo;administrateur système
à être pleinement attentif à ce qui est exécuté dans le système, ce qui
est un bon point pour la sécurité.</p>
<ul>
<li><a href="https://man.openbsd.org/rcctl" rel="external">rcctl man page</a></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>La plupart des &ldquo;fonctionnalités de sécurité&rdquo; vues devraient être considérées
comme de bonnes pratiques et non pas comme des fonctionnalités. Beaucoup
des bonnes pratiques suivantes pourraient être facilement mises en œuvre :
Limiter les ressources utilisateurs, réduire les privilèges des démons,
être strict dans l&rsquo;utilisation de la mémoire, fournir une bonne documentation,
démarrer le strict minimum requis de services et fournir à l&rsquo;utilisateur
une installation par défaut propre qui peut être personnalisé plus tard.</p>
<p>Il y a aussi de nombreuses autres fonctionnalités qui ont été ajoutées,
que je ne comprend pas pleinement ; je préfère laisser au lecteur le soin
d&rsquo;en prendre connaissance.</p>
<ul>
<li><a href="https://www.openbsd.org/papers/bsdtw.pdf" rel="external">« Mitigations and other real security features » by Theo De Raadt</a></li>
<li><a href="https://www.openbsd.org/innovations.html" rel="external">OpenBSD innovations</a></li>
<li><a href="https://www.openbsd.org/events.html" rel="external">OpenBSD events, often including slides or videos</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction du Tutoriel EN → FR &#39;What security does a default OpenBSD installation offer?&#39; expliquant ce qu&#39;il faut attendre de la sécurité par défaut sous OpenBSD, selon Solène Rapenne]]></summary>
        <published>2021-02-20T16:18:45+01:00</published>
        <updated>2023-05-03T06:30:55+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c4134978-d080-03e0-cff8-2401265a85ce</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/smartmontools/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : smartmontools</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="smartmontools" scheme="http://doc.huc.fr.eu.org/fr/tags/smartmontools/" />
        <category term="smartctl" scheme="http://doc.huc.fr.eu.org/fr/tags/smartctl/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Sous OpenBSD, il est possible de surveiller l&rsquo;état de son|ses disque(s)
dur(s), nativement par le biais de l&rsquo;outil <strong>atactl</strong>, qui reste basique,
mais fait le job.</p>
<p>Néanmoins concentrons-nous sur le projet <strong>smartmontools</strong>… qui est
disponible en tant que paquet.</p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>smarmontools</strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration est <code>/etc/smartd.conf</code>.</p>
<p>Selon l&rsquo;emplacement de votre disque dur, il peut être intéressant de le
paramètrer ainsi :</p>
<p><code>/dev/sd0c -a -o on -S on -s (S/../.././02|L/../../7/03)</code></p>
<p>Qui :</p>
<ul>
<li>surveillera tous les attributs</li>
<li>activera la collection des données automatiquement</li>
<li>effectuera un test court tous les jours à partir de 2h du matin</li>
<li>effectuera un test long tous les dimanches dès 3h du matin.</li>
</ul>
<hr>
<p>⇒ Syntaxe :</p>
<p>la syntaxe entre parenthèses est : <code>T/MM/DD/d/HH</code></p>
<p>Où :</p>
<ul>
<li><strong>T</strong> est le type de Test :
<ul>
<li><strong>C</strong> pour un test de transmission</li>
<li><strong>L</strong> pour un test long</li>
<li><strong>O</strong> pour un test immédiat hors-ligne</li>
<li><strong>S</strong> pour un test court</li>
</ul>
</li>
<li><strong>MM</strong> est le mois de l&rsquo;année en format numérique, de 01 à 12</li>
<li><strong>DD</strong> est le jour dans le mois, en format numérique, de 01 à 31</li>
<li><strong>d</strong> est le jour dans la semaine, en format numérique, de 1 à 7 ; 1 étant Lundi…</li>
<li><strong>HH</strong> est l&rsquo;heure, de 01 à 23</li>
</ul>
<hr>
<p>⇒ Activation du démon logiciel :</p>
<p><code># rcctl enable smartd</code> <br>
<code># rcctl start smartd</code></p>
<h2 id="utilisation">Utilisation</h2>
<h3 id="informations">Informations</h3>
<p>⇒ Obtenir les informations du disque dur :</p>
<p><code># smartcl -i /dev/sd1c</code></p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -i /dev/sd1c                  
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF INFORMATION <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>Model Family:     SAMSUNG SpinPoint F1 DT
</span></span><span style="display:flex;"><span>Device Model:     SAMSUNG HD103UJ
</span></span><span style="display:flex;"><span>Serial Number:    S13PJ9CZ200215
</span></span><span style="display:flex;"><span>LU WWN Device Id: <span style="color:#f99b15">5</span> 0024e9 201ee0406
</span></span><span style="display:flex;"><span>Firmware Version: 1AA01118
</span></span><span style="display:flex;"><span>User Capacity:    1,000,204,886,016 bytes <span style="color:#5bc4bf">[</span>1.00 TB<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Sector Size:      <span style="color:#f99b15">512</span> bytes logical/physical
</span></span><span style="display:flex;"><span>Device is:        In smartctl database <span style="color:#5bc4bf">[</span><span style="color:#815ba4">for</span> details use: -P show<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>ATA Version is:   ATA/ATAPI-7, ATA8-ACS T13/1699-D revision 3b
</span></span><span style="display:flex;"><span>Local Time is:    Fri Feb <span style="color:#f99b15">19</span> 12:27:52 <span style="color:#f99b15">2021</span> CET
</span></span><span style="display:flex;"><span>SMART support is: Available - device has SMART capability.
</span></span><span style="display:flex;"><span>SMART support is: Enabled
</span></span></code></pre></div><hr>
<h3 id="exécution-de-tests">Exécution de tests</h3>
<p>⇒ Exécuter un test smart court :</p>
<p><code># smartctl -t short /dev/sd1c</code></p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -t short /dev/sd1c            
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF OFFLINE IMMEDIATE AND SELF-TEST <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>Sending command: <span style="color:#48b685">&#34;Execute SMART Short self-test routine immediately in off-line mode&#34;</span>.
</span></span><span style="display:flex;"><span>Drive command <span style="color:#48b685">&#34;Execute SMART Short self-test routine immediately in off-line mode&#34;</span> successful.
</span></span><span style="display:flex;"><span>Testing has begun.
</span></span><span style="display:flex;"><span>Please wait <span style="color:#f99b15">2</span> minutes <span style="color:#815ba4">for</span> test to complete.
</span></span><span style="display:flex;"><span>Test will complete after Fri Feb <span style="color:#f99b15">19</span> 12:30:26 <span style="color:#f99b15">2021</span> CET
</span></span><span style="display:flex;"><span>Use smartctl -X to abort test.
</span></span></code></pre></div><p>⇒ Exécuter un test smart long :</p>
<p><code># smartctl -t long /dev/sd1c</code></p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -t long /dev/sd1c               
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF OFFLINE IMMEDIATE AND SELF-TEST <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>Sending command: <span style="color:#48b685">&#34;Execute SMART Extended self-test routine immediately in off-line mode&#34;</span>.
</span></span><span style="display:flex;"><span>Drive command <span style="color:#48b685">&#34;Execute SMART Extended self-test routine immediately in off-line mode&#34;</span> successful.
</span></span><span style="display:flex;"><span>Testing has begun.
</span></span><span style="display:flex;"><span>Please wait <span style="color:#f99b15">228</span> minutes <span style="color:#815ba4">for</span> test to complete.
</span></span><span style="display:flex;"><span>Test will complete after Fri Feb <span style="color:#f99b15">19</span> 17:00:35 <span style="color:#f99b15">2021</span> CET
</span></span><span style="display:flex;"><span>Use smartctl -X to abort test.
</span></span></code></pre></div><hr>
<h3 id="gestion-des-logs">Gestion des logs</h3>
<p>⇒ Vérifier rapidement les erreurs :</p>
<p><code># smartctl -l error /dev/sd1c</code></p>
<p>Exemple correct :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -l error /dev/sd1c 
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF READ SMART DATA <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>SMART Error Log Version: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>No Errors Logged
</span></span></code></pre></div><p>⇒ Vérifier les résultats des auto-test :</p>
<p><code># smartctl -l selftest /dev/sd1c</code></p>
<p>Exemple correct :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -l selftest /dev/sd1c
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF READ SMART DATA <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>SMART Self-test log structure revision number <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Num  Test_Description    Status                  Remaining  LifeTime<span style="color:#5bc4bf">(</span>hours<span style="color:#5bc4bf">)</span>  LBA_of_first_error
</span></span><span style="display:flex;"><span><span style="color:#776e71"># 1  Short offline       Completed without error       00%     21190         -</span>
</span></span></code></pre></div><p>Exemple avec erreur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -l selftest /dev/sd1c 
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF READ SMART DATA <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>SMART Self-test log structure revision number <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Num  Test_Description    Status                  Remaining  LifeTime<span style="color:#5bc4bf">(</span>hours<span style="color:#5bc4bf">)</span>  LBA_of_first_error
</span></span><span style="display:flex;"><span><span style="color:#776e71"># 1  Short offline       Completed: read failure       20%     20826         1800697692</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># 2  Short offline       Completed without error       00%     20817         -</span>
</span></span></code></pre></div><p>Ici l&rsquo;auto-test ne va pas jusqu&rsquo;au bout de l&rsquo;analyse.</p>
<hr>
<h3 id="affichage-de-la-température">Affichage de la température</h3>
<p>⇒ Afficher la température du disque :</p>
<p><code># smartctl -l scttemp /dev/sd1c</code></p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ doas smartctl -l scttemp /dev/sd1c 
</span></span><span style="display:flex;"><span>smartctl 7.1 2019-12-30 r5022 <span style="color:#5bc4bf">[</span>x86_64-unknown-openbsd6.8<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>local build<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">===</span> START OF READ SMART DATA <span style="color:#ef6155">SECTION</span> <span style="color:#5bc4bf">===</span>
</span></span><span style="display:flex;"><span>SCT Status Version:                  <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>SCT Version <span style="color:#5bc4bf">(</span>vendor specific<span style="color:#5bc4bf">)</span>:       <span style="color:#f99b15">256</span> <span style="color:#5bc4bf">(</span>0x0100<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Device State:                        Active <span style="color:#5bc4bf">(</span>0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Current Temperature:                    <span style="color:#f99b15">27</span> Celsius
</span></span><span style="display:flex;"><span>Power Cycle Min/Max Temperature:     --/27 Celsius
</span></span><span style="display:flex;"><span>Lifetime    Min/Max Temperature:     --/55 Celsius
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>SCT Temperature History Version:     <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>Temperature Sampling Period:         <span style="color:#f99b15">1</span> minute
</span></span><span style="display:flex;"><span>Temperature Logging Interval:        <span style="color:#f99b15">1</span> minute
</span></span><span style="display:flex;"><span>Min/Max recommended Temperature:     -4/72 Celsius
</span></span><span style="display:flex;"><span>Min/Max Temperature Limit:           -9/77 Celsius
</span></span><span style="display:flex;"><span>Temperature History Size <span style="color:#5bc4bf">(</span>Index<span style="color:#5bc4bf">)</span>:    <span style="color:#f99b15">128</span> <span style="color:#5bc4bf">(</span>29<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Index    Estimated Time   Temperature Celsius
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">30</span>    2021-02-19 10:47    <span style="color:#f99b15">24</span>  *****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">31</span>    2021-02-19 10:48    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">32</span>    2021-02-19 10:49    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">33</span>    2021-02-19 10:50    <span style="color:#f99b15">24</span>  *****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">34</span>    2021-02-19 10:51    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">35</span>    2021-02-19 10:52    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">36</span>    2021-02-19 10:53    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">37</span>    2021-02-19 10:54    <span style="color:#f99b15">24</span>  *****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">38</span>    2021-02-19 10:55    <span style="color:#f99b15">23</span>  ****
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">39</span>    2021-02-19 10:56    <span style="color:#f99b15">24</span>  *****
</span></span></code></pre></div><hr>
<h3 id="toutes-les-données">Toutes les données</h3>
<p>⇒ Afficher les données complètes :</p>
<p><code># smartctl -a /dev/sd1c</code></p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li><code>$ man smartd smartd.conf</code></li>
<li>La documentation officielle du projet sur <a href="http://smartmontools.org" rel="external">smartmontools.org</a>.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications de l&#39;outil smartmontools sous OpenBSD]]></summary>
        <published>2021-02-19T12:44:58+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f562f2d1-f486-d125-7d09-3ee967b65a2f</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-gemini-gopher/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Gemini, Gopher… &#39;Quoi d&#39;autres ?!&#39;</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="Gemini" scheme="http://doc.huc.fr.eu.org/fr/tags/gemini/" />
        <category term="Gopher" scheme="http://doc.huc.fr.eu.org/fr/tags/gopher/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Gemini et Gopher sont deux autres Internet, tout à fait légaux, dont le
but est de la publication &ldquo;légère&rdquo; d&rsquo;informations, principalement du texte.
En fait, historiquement Gopher est né en 1991, en parallèle du Grand Net
sur protocole HTTP ; tandis que Gemini est un protocole de communication
récent, né courant juin 2019.</p>
<p>Tout comme le Grand Net sur HTTP(S), Gopher et Gemini ont leur propre
protocole de communication, portant leur propre nom :</p>
<ul>
<li>Gemini : <code>gemini://</code></li>
<li>Gopher : <code>gopher://</code></li>
</ul>
<p>À savoir que le protocole gemini est basé sur TLS directement… <br>
De plus, bien que ces protocoles soient cloisonnés entre eux, en effet
les protocoles Gemini, Gopher et HTTP(S) sont des réseaux différents,
par des services différents, sur des ports différents, il existe des
passerelles du côté de Gemini et Gopher, vers HTTP(S).</p>
<p>Ne cherchez pas toutes les fioritures que permet le protocole HTTP(S),
exit les scripts CSS, JS, voire les images, avec Gemini et Gopher, on se
concentre principalement sur la ressource importante : le texte. <br>
<em>cf : cherchez <strong>Low Web</strong></em> ;-)</p>
<hr>
<p>Comment modifier Hugo pour lui faire générer des fichiers à publier sur
les protocoles Gemini, et Gopher ?</p>
<p>Dans les faits, vous prendrez plus de temps à lire cet article,
qu&rsquo;à faire vos modifications basiques, qui sont possibles d&rsquo;être faites
en moins de 5 minutes !!!</p>
<p><em>Il y a(ura) certainements de petites modifications à apporter… mais l&rsquo;esprit
de l&rsquo;article est là, et fonctionnel.</em> ;-)</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : les modifications ci-dessous actuellement sont fonctionnelles
dans le contexte d&rsquo;une configuration basique de Hugo.</p>
<p>Dans le cas d&rsquo;un site multi-langue, ou que vous avez paramétré la variable
<code>permalinks.posts</code>, le résultat attendu n&rsquo;aura pas lieu.</p>
<p>Dans les faits, le repertoire géré par la variable <code>path</code> est lié au répertoire
de sortie. Ainsi dans le contexte multilangue, vous retrouverez dans chaque
répertoire de langue un répertoire nommé selon le protocole cible !</p>
<p>Ainsi, vous aurez dans le répertoire <code>public/</code>, d&rsquo;abord les répertoires de
langue, puis le répertoire <code>gemini</code> ou <code>gopher</code>.</p>
<p>Alors que dans une configuration basique, le répertoire <code>gemini</code> ou <code>gopher</code>
sera directement déposé à la racine du répertoire <code>public/</code>.</p>
</div>

<h2 id="gemini">Gemini</h2>
<p>Concernant les modifications pour Gemini, voici le propos :</p>
<h3 id="configuration-pour-gemini">Configuration pour Gemini</h3>
<p>Modifions très simplement le fichier de configuration de Hugo <code>config.toml</code> :</p>
<h4 id="configuration-gemini--ajout-du-mimetype">Configuration Gemini : ajout du mimetype</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span><span style="color:#776e71"># Gemini</span>
</span></span><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;text/gemini&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffixes</span> = [<span style="color:#48b685">&#34;gmi&#34;</span>]
</span></span></code></pre></div><h4 id="configuration-gemini--ajout-du-format-de-sortie">Configuration Gemini : ajout du format de sortie</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span><span style="color:#776e71"># Gemini</span>
</span></span><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">Gemini</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isHTML</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;text/gemini&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name</span> = <span style="color:#48b685">&#34;gemini&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">path</span> = <span style="color:#48b685">&#34;gemini/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">permalinkable</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">protocol</span> = <span style="color:#48b685">&#34;gemini://&#34;</span>
</span></span></code></pre></div><p>Remarquons que la publication des fichiers gmi auront lieu dans un répertoire
distinct, nommé <strong>gemini</strong>, dans le répertoire <code>public/</code>.
Ce seront de purs fichiers texte, ayant l&rsquo;extension <code>.gmi</code>.</p>
<hr>
<p>Puis dans la configuration de la sortie, par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;gemini&#34;</span>, <span style="color:#ef6155">…</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">page</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;gemini&#34;</span>, <span style="color:#ef6155">…</span>]
</span></span></code></pre></div><p><em>Bien sûr, ne pas utiliser les &lsquo;…&rsquo; dans votre configuration ; ici, ils
expriment les autres options de génération possible, sans les nommer !</em></p>
<hr>
<p>Gemini est capable de lire des fichiers au format RSS, ce qui nous permet
de générer un flux RSS ; ajoutons un nouveau format de sortie spécifique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">GeminiRSS</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isHTML</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;application/rss+xml&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name</span> = <span style="color:#48b685">&#34;GeminiRSS&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">protocol</span> = <span style="color:#48b685">&#34;gemini://&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">path</span> = <span style="color:#48b685">&#34;gemini/&#34;</span>
</span></span></code></pre></div><p>et modifions la génération de sortie, tel que par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;gemini&#34;</span>, <span style="color:#48b685">&#34;GeminiRSS&#34;</span>, <span style="color:#ef6155">…</span>]
</span></span></code></pre></div><h3 id="layouts-pour-gemini">Layouts pour Gemini</h3>
<h4 id="indexgmi">index.gmi</h4>
<p>Ajoutons un fichier <code>index.gmi</code> dans le repertoire <code>layouts/</code>, qui pour
l&rsquo;exemple aura le code hugo basique suivant :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{ range .Paginator.Pages }}
{{- if .OutputFormats.Get &#34;gemini&#34; }}
⇒ {{ replace .Permalink &#34;/gemini&#34; &#34;&#34; 1 }} {{ .Date.Format &#34;January 2, 2006&#34; }}: {{ .Title | safeHTML }}{{ end }}{{ end }}
</code></pre><p><em>Libre à vous de modifier, améliorer la pertinence du code Hugo pour obtenir
le contenu que vous désirez publier…</em></p>
<hr>
<h4 id="indexgeminirssxml">index.geminirss.xml</h4>
<p>Si vous désirez gérez un flux RSS pour Gemini, selon la configuration ci-dessus,
ajoutons un fichier <code>index.geminirss.xml</code>, ayant le contenu de génération
tel que :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := slice -}}
{{- if or $.IsHome $.IsSection -}}
{{- $pages = $pctx.RegularPages -}}
{{- else -}}
{{- $pages = $pctx.Pages -}}
{{- end -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
{{- printf &#34;&lt;?xml version=\&#34;1.0\&#34; encoding=\&#34;utf-8\&#34; standalone=\&#34;yes\&#34;?&gt;&#34; | safeHTML }}
&lt;rss version=&#34;2.0&#34; xmlns:atom=&#34;http://www.w3.org/2005/Atom&#34;&gt;
  &lt;channel&gt;
    &lt;title&gt;{{ .Site.Title | safeHTML }}&lt;/title&gt;
    &lt;link&gt;{{ replace .Permalink &#34;https&#34; &#34;gemini&#34; 1 }}&lt;/link&gt;
    &lt;description&gt;{{ .Site.Params.siteDescription | safeHTML }}&lt;/description&gt;
    &lt;generator&gt;Hugo {{ hugo.Version }}  gohugo.io&lt;/generator&gt;{{ with .Site.LanguageCode }}
    &lt;language&gt;{{.}}&lt;/language&gt;{{end}}{{ with .Site.Params.Author.email }}
    &lt;managingEditor&gt;{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}&lt;/managingEditor&gt;{{end}}{{ with .Site.Params.Author.email }}
    &lt;webMaster&gt;{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}&lt;/webMaster&gt;{{end}}{{ with .Site.Copyright }}
    &lt;copyright&gt;{{.}}&lt;/copyright&gt;{{end}}{{ if not .Date.IsZero }}
    &lt;lastBuildDate&gt;{{ .Date.Format &#34;Mon, 02 Jan 2006 15:04:05 -0700&#34; | safeHTML }}&lt;/lastBuildDate&gt;{{ end }}
    {{ with .OutputFormats.Get &#34;RSS&#34; }}
      {{ printf &#34;&lt;atom:link href=%q rel=\&#34;self\&#34; type=%q /&gt;&#34; .Permalink .MediaType | safeHTML }}
    {{ end }}
    {{ range $pages }}
    {{- if .OutputFormats.Get &#34;gemini&#34; -}}
    &lt;item&gt;
      &lt;title&gt;{{ .Title | safeHTML }}&lt;/title&gt;
      {{ with .OutputFormats.Get &#34;gemini&#34; }}
      &lt;link&gt;{{replace .Permalink &#34;/gemini&#34; &#34;&#34; 1}}&lt;/link&gt;
      {{ end }}
      &lt;pubDate&gt;{{ .Date.Format &#34;Mon, 02 Jan 2006 15:04:05 -0700&#34; | safeHTML }}&lt;/pubDate&gt;
      {{ with .Site.Params.Author.email }}&lt;author&gt;{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}&lt;/author&gt;{{end}}
      {{ with .OutputFormats.Get &#34;gemini&#34; }}
      &lt;guid&gt;{{replace .Permalink &#34;/gemini&#34; &#34;&#34; 1}}&lt;/guid&gt;
      {{ end }}
    &lt;/item&gt;
    {{- end -}}
    {{ end }}
  &lt;/channel&gt;
&lt;/rss&gt;
</code></pre><h4 id="singlegmi">single.gmi</h4>
<p>Dans le répertoire enfant <code>_default</code> du sous répertoire <code>layouts/</code>, ajoutons
un simple fichier <code>single.gmi</code> qui s&rsquo;occupera principalement de la génération
des pages :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo"># {{ $.Title | safeHTML }}

{{ .RawContent }}
</code></pre><p>C&rsquo;est basique ; ca fait le boulot, simplement. Là encore libre à vous de
modifier, ajouter votre code Hugo, pour générer plus proprement afin de
débarrasser du code Markdown, par exemple :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{ $scratch := newScratch }}
{{ $content := .RawContent -}}
{{ $content := $content | replaceRE `#### ` &#34;### &#34; -}}
{{ $content := $content | replaceRE `\n- (.+?)` &#34;\n* $1&#34; -}}
{{ $content := $content | replaceRE `\n(\d+). (.+?)` &#34;\n* $2&#34; -}}
{{ $content := $content | replaceRE `\[\^(.+?)\]:?` &#34;&#34; -}}
{{ $content := $content | replaceRE `&lt;br/??&gt;` &#34;\n&#34; -}}
{{ $content := $content | replaceRE `&lt;a .*href=&#34;(.+?)&#34;.*&gt;(.+?)&lt;/a&gt;` &#34;[$2]($1)&#34; -}}
{{ $content := $content | replaceRE `\sgemini://(\S*)` &#34; [gemini://$1](gemini://$1)&#34; -}}
{{ $content := $content | replaceRE &#34;([^`])&lt;.*?&gt;([^`])&#34; &#34;$1$2&#34; -}}
{{ $content := $content | replaceRE `\n\n!\[.*\]\((.+?) \&#34;(.+?)\&#34;\)` &#34;\n\n=&gt; $1 Image: $2&#34; -}}
{{ $content := $content | replaceRE `\n\n!\[.*]\((.+?)\)` &#34;\n\n=&gt; $1 Embedded Image: $1&#34; -}}
{{ $links := findRE `\n=&gt; ` $content }}{{ $scratch.Set &#34;ref&#34; (add (len $links) 1) }}
{{ $refs := findRE `\[.+?\]\(.+?\)` $content }}
{{ $scratch.Set &#34;content&#34; $content }}{{ range $refs }}{{ $ref := $scratch.Get &#34;ref&#34; }}{{ $contentInLoop := $scratch.Get &#34;content&#34; }}{{ $url := (printf &#34;%s #%d&#34; . $ref) }}{{ $contentInLoop := replace $contentInLoop . $url -}}{{ $scratch.Set &#34;content&#34; $contentInLoop }}{{ $scratch.Set &#34;ref&#34; (add $ref 1) }}{{ end }}{{ $content := $scratch.Get &#34;content&#34; | replaceRE `\[(.+?)\]\((.+?)\) #(\d+)` &#34;$1 [$3]&#34; -}}
{{ $content | safeHTML }}
</code></pre><p><strong>Explications :</strong></p>
<p><em>Ce code - qui fait très bien son travail - est un copié-collé du code créé par un certain
<a href="https://brainbaking.com/post/2021/04/using-hugo-to-launch-a-gemini-capsule/" rel="external">Wouter Groeneveld</a> ;
les explications sont fournies en anglais. N&rsquo;ayant pas l&rsquo;utilité de gérer
des fichiers audio, vidéo, localement ou sur d&rsquo;autres plateformes, j&rsquo;ai
simplement supprimé les lignes correspondantes.</em></p>
<hr>
<p>Voilà <em>(pour la partie Gemini)</em> !</p>
<p><em>Il ne reste plus qu&rsquo;à publier…</em></p>
<h2 id="gopher">Gopher</h2>
<p>Attaquons les modifications de configurations et de calques pour générer
les fichiers textes pour Gopher. Là encore, nous générons les fichiers
dans un répertoire dédié, nommé <strong>gopher</strong> dans le répertoire <code>public/</code>
afin de faciliter la synchronisation vers le serveur gopher…</p>
<h3 id="configuration-pour-gopher">Configuration pour Gopher</h3>
<p>Modifions donc le fichier de configuration de Hugo, pour ajouter les formats
de génération. En effet :</p>
<ul>
<li>le premier va nous être utile pour la génération des pages, qui porteront
le nom <strong>index</strong>, dans leur propre répertoire</li>
<li>le second pour générer les fichiers d&rsquo;indexation <strong>gophermap</strong></li>
</ul>
<p>Tous auront l&rsquo;extension de fichier <code>.txt</code> et seront publiés dans un sous-répertoire
nommé <strong>gopher</strong> du répertoire <code>public/</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">Gopher</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;index&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isHTML</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;text/plain&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">noUgly</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">path</span> = <span style="color:#48b685">&#34;gopher/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">protocol</span> = <span style="color:#48b685">&#34;gopher://&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">GopherMap</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;gophermap&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isHTML</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;text/plain&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">noUgly</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">path</span> = <span style="color:#48b685">&#34;gopher/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">protocol</span> = <span style="color:#48b685">&#34;gopher://&#34;</span>
</span></span></code></pre></div><p>Puis modifions la génération des sorties, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;gemini&#34;</span>, <span style="color:#48b685">&#34;GeminiRSS&#34;</span>, <span style="color:#48b685">&#34;gophermap&#34;</span>, <span style="color:#ef6155">…</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">page</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;gemini&#34;</span>, <span style="color:#48b685">&#34;gopher&#34;</span>]
</span></span></code></pre></div><h3 id="layouts-pour-gopher">Layouts pour Gopher</h3>
<p>Attaquons la partie des fichiers à créer dans le sous-répertoire <code>layouts/</code>.</p>
<h4 id="indexgophermaptxt">index.gophermap.txt</h4>
<p>Restons simple :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{ .Site.Title | safeHTML }}

⇒ Menu :

{{ range .Site.Menus.main }}
{{- if (or (eq .Identifier &#34;search&#34;) (eq .Identifier &#34;lang-switcher&#34;) (eq .Identifier &#34;theme-switcher&#34;) ) }}
{{- else }}
1{{ .Name }}    {{ .URL | safeURL }} 70
{{- end -}}
{{ end }}

⇒ Articles les plus récents :
{{ $nb := 7 }}
{{ range first $nb .Paginator.Pages }}
0{{ .Title }}   {{ with .OutputFormats.Get &#34;gopher&#34; }}  {{ replaceRE &#34;/gopher&#34; &#34;&#34; .RelPermalink }} 70 {{ end }}
{{- end }}
</code></pre><p>Ce fichier <strong>gophermap</strong> nous permet de publier simplement l&rsquo;équivalent
du menu principal de Hugo, ainsi que promouvoir les <code>x</code> derniers
articles. - <em>ici, les 7 derniers</em> -</p>
<p><em>Pour ceux qui n&rsquo;auraient pas compris : les fichiers gophermap sont des
fichiers d&rsquo;indexation de contenu…</em></p>
<h4 id="listgophermaptxt">list.gophermap.txt</h4>
<p>Ajoutons dans le répertoire enfant <code>_default/</code> du sous-répertoire <code>layout/</code>,
un fichier de génération de liste, qui peut avoir le contenu basique suivant :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">!{{ .Title | safeHTML }}

{{ .RawContent }}

{{ range .Paginator.Pages }}
0{{ .Title }}   {{ with .OutputFormats.Get &#34;gopher&#34; -}}{{ .RelPermalink }}  {{ $.Site.Params.hostname}} 70 {{ end }}
{{ end }}
</code></pre><h4 id="singlegophertxt">single.gopher.txt</h4>
<p>Pour la génération des pages, ajoutons dans le même sous-répertoire <code>_default/</code>,
un fichier nommé <code>single.gopher.txt</code> qui peut avoir le contenu basique suivant :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">!{{ .Title | safeHTML }}

{{ .Date.Format (.Site.Params.dateform | default &#34;01 January 2006&#34;) }} · {{ .ReadingTime }} minute(s) de lecture.
{{ if .Params.tags }}
Tags :  {{ range .Params.tags }}{{ . }} {{ end }}
{{ end }}

---

{{ .RawContent }}

---

Publié le : {{.Date.Format &#34;2 January 2006&#34;}}.

0⇒ Revenir à la page d&#39;accueil : / 70
h⇒ Lire l&#39;article “{{ $.Title | safeHTML }}” sur le protocole HTTP(S) : {{ .Permalink | safeURL }} 443

Le contenu de ce site est diffusé sous Licence {{ $.Site.Copyright | safeHTML }}.
</code></pre><hr>
<p><em>Encore une fois, à vous de modifier à votre convenance et autres imaginations
nécessaires pour votre promotion…</em></p>
<p>Voilà <em>(pour la partie Gopher)</em> !</p>
<p><em>Il ne reste plus qu&rsquo;à publier…</em></p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>le projet Gemini : <a href="https://gemini.circumlunar.space/" rel="external">https://gemini.circumlunar.space/</a></li>
</ul>
<h4 id="wikipedia">Wikipedia</h4>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Gemini" title="Article Wikipédia : Gemini">Gemini <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://fr.wikipedia.org/wiki/Gopher" title="Article Wikipédia : Gopher">Gopher <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li><strong>Drew Devault</strong> : un des premiers à modifier Hugo pour générer du contenu pour Gemini - <em>voici son <a href="https://git.sr.ht/~sircmpwn/drewdevault.com/tree/master" rel="external">dépôt Git</a> pour exemple !</em></li>
<li><strong>Sylvain Durant</strong> : un parisien qui fait simple et dont je me suis inspiré pour la communauté &ldquo;OpenBSD Pour Tous&rdquo; : <a href="https://sylvaindurand.org/gemini-and-hugo/" rel="external">https://sylvaindurand.org/gemini-and-hugo/</a></li>
<li>le dépôt Git de la communauté &ldquo;OpenBSD Pour Tous&rdquo;, où vous retrouverez les modifications de génération pour gopher et gemini : <a href="https://tildegit.org/obsd4a/www" rel="external">https://tildegit.org/obsd4a/www</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment modifier simplement Hugo, en 5 minutes, pour qu&#39;il génére les fichiers afin de publier sur les protocoles Gemini, Gopher…]]></summary>
        <published>2021-01-24T17:12:08+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f9d54c5f-f4ab-e2ff-881a-d0f8a6624826</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/solene-rapenne/cryptpad-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Héberger votre suite web office Cryptpad sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Cryptpad" scheme="http://doc.huc.fr.eu.org/fr/tags/cryptpad/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://dataswamp.org/~solene/2020-12-14-cryptpad-openbsd.html" rel="external">Host your Cryptpad web office suite with OpenBSD</a></strong>&rdquo;,
écrit par Solène Rapenne.</p>
<hr>
<h1 id="héberger-votre-suite-web-office-cryptpad-sous-openbsd">Héberger votre suite web office Cryptpad sous OpenBSD</h1>
<p>Dans cet article, j&rsquo;expliquerai comment déployer votre propre instance
de <a href="https://cryptpad.fr/" rel="external">Cryptpad</a> sous OpenBSD. Cryptpad est une suite web office permettant
de collaborer en temps réel sur des documents. Cryptpad est écrit en
JavaScript et le démon agit en tant que serveur web.</p>
<h2 id="pré-requis">Pré-requis</h2>
<p>Vous avez besoin d&rsquo;installer les paquets <strong>git</strong>, <strong>node</strong>, <strong>automake</strong>
et <strong>autoconfig</strong> afin d&rsquo;être capable de récupèrer les sources et d&rsquo;exécuter
le programme.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add node git autoconf--%2.69 automake--%1.16</span>
</span></span></code></pre></div><p>Un autre logiciel en amont est requis pour assurer les connexions
TLS et sécuriser les accès réseaux à l&rsquo;instance Cryptpad. Cela peut être
<strong>relayd</strong>, <strong>haproxy</strong>, <strong>nginx</strong> ou <strong>lighttpd</strong>. Je couvre le paramétrage
en utilisant httpd, et relayd. Notez que les développeurs de Cryptpad ne
fournissent du support que seulement pour les utilisateurs de Nginx.</p>
<h2 id="installation">Installation</h2>
<p>Je recommande réellement l&rsquo;utilisation d&rsquo;utilisateur dédié au service.
Nous créerons un nouvel utilisateur par la commande :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># useradd -m _cryptpad</span>
</span></span></code></pre></div><p>Ensuite, nous continuerons l&rsquo;installation logiciel avec l&rsquo;utilisateur
<code>_cryptpad</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># su -l _cryptpad</span>
</span></span></code></pre></div><p>Nous suivrons principalement le <a href="https://github.com/xwiki-labs/cryptpad/wiki/Installation-guide" rel="external">guide d&rsquo;installation officiel</a> à certaines
exceptions près afin d&rsquo;adapter à OpenBSD :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>$ git clone https://github.com/xwiki-labs/cryptpad
</span></span><span style="display:flex;"><span>$ cd cryptpad
</span></span><span style="display:flex;"><span>$ env <span style="color:#ef6155">AUTOMAKE_VERSION</span><span style="color:#5bc4bf">=</span>1.16 <span style="color:#ef6155">AUTOCONF_VERSION</span><span style="color:#5bc4bf">=</span>2.69 <span style="color:#ef6155">CC</span><span style="color:#5bc4bf">=</span>clang <span style="color:#ef6155">CXX</span><span style="color:#5bc4bf">=</span>clang++ npm install
</span></span><span style="display:flex;"><span>$ env <span style="color:#ef6155">AUTOMAKE_VERSION</span><span style="color:#5bc4bf">=</span>1.16 <span style="color:#ef6155">AUTOCONF_VERSION</span><span style="color:#5bc4bf">=</span>2.69 <span style="color:#ef6155">CC</span><span style="color:#5bc4bf">=</span>clang <span style="color:#ef6155">CXX</span><span style="color:#5bc4bf">=</span>clang++ npm install bower
</span></span><span style="display:flex;"><span>$ node_modules/.bin/bower install
</span></span><span style="display:flex;"><span>$ cp config/config.example.js config/config.js
</span></span></code></pre></div><h2 id="configuration">Configuration</h2>
<p>Voici les quelques variables importantes à personnaliser :</p>
<ul>
<li><strong>httpUnsafeOrigin</strong> devrait être l&rsquo;adresse publique sur laquelle Cryptpad
sera disponible. Cela devrait être certainement un lien HTTPS avec un
nom d&rsquo;hôte. J&rsquo;utiliserais <code>https://cryptpad.kongroo.eu</code>.</li>
<li><strong>httpSafeOrigin</strong> devrait être une adresse publique différente de la
précédente. Cryptpad requiert deux adresses différentes pour fonctionner.
J&rsquo;utiliserais <code>https://api.cryptpad.kongroo.eu</code>.</li>
<li><strong>adminEmail</strong> doit être une adresse de courriel valide utilisé par l&rsquo;administrateur
(certainement vous-même).</li>
</ul>
<h2 id="créer-un-fichier-rc-pour-démarrer-le-service">Créer un fichier rc pour démarrer le service</h2>
<p>Nous avons besoin d&rsquo;automatiser le démarrage proprement, en même temps que
celui du système.</p>
<p>Créez le fichier <code>/etc/rc.d/cryptpad</code> :</p>
<pre tabindex="0"><code class="language-rc" data-lang="rc">#!/bin/ksh

daemon=&#34;/usr/local/bin/node&#34;
daemon_flags=&#34;server&#34;
daemon_user=&#34;_cryptpad&#34;
location=&#34;/home/_cryptpad/cryptpad&#34;

. /etc/rc.d/rc.subr

rc_start() {
    ${rcexec} &#34;cd ${location}; ${daemon} ${daemon_flags}&#34;
}

rc_bg=YES
rc_cmd $1
</code></pre><p>Activez et démarrez le service avec le contrôleur <code>rcctl</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable cryptpad</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start cryptpad</span>
</span></span></code></pre></div><h2 id="fonctionnement">Fonctionnement</h2>
<h3 id="création-dun-compte-administrateur">Création d&rsquo;un compte administrateur</h3>
<p>Enregistrez-vous sur votre instance Cryptpad puis allez à la page &ldquo;Settings&rdquo;
de votre profil : copiez votre clé public de signature.</p>
<p>Éditez le fichier <code>config.js</code> et cherchez <code>adminKeys</code> ; décommentez la section
en supprimant les <code>/*</code> et <code>*/</code> autour, puis supprimez la clé d&rsquo;exemple pour
copier la vôtre, tel ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#06b6ef">adminKeys</span><span style="color:#5bc4bf">:</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;[solene@cryptpad.kongroo.eu/YzfbEYwZq6Xhl7ET6AHD01w3QqOE7STYgGglgSTgWfk=]&#34;</span>,
</span></span><span style="display:flex;"><span>],
</span></span></code></pre></div><p>Redémarrez Cryptpad ; l&rsquo;utilisateur est maintenant administrateur et a accès
au nouveau panel d&rsquo;administration depuis l&rsquo;application web.</p>
<h3 id="sauvegarde">Sauvegarde</h3>
<p>Vous avez besoin de sauvegarder les répertoires <code>data</code> et <code>datastore</code> qui
sont dans le répertoire de Cryptpad.</p>
<h2 id="configuration-supplémentaire">Configuration supplémentaire</h2>
<p>Dans cette section, j&rsquo;expliquerai comment générer votre certificat TLS avec
acme-client et comment configurer httpd et relayd pour publier cryptpad.
Je considère cela en plus de l&rsquo;actuel article, car si vous utilisez déjà
nginx, et avez une installation pour générer des certificats, vous
n&rsquo;en avez pas besoin. Si vous démarrez de zéro, c&rsquo;est la manière la plus
simple pour obtenir un résultat.</p>
<p>À partir de là, je considère que vous utilisez OpenBSD et que vos fichiers
de configuration sont vierges.</p>
<p>J&rsquo;utiliserai pour l&rsquo;exemple le domaine <strong>kongroo.eu</strong>.</p>
<h3 id="httpd">httpd</h3>
<p>Nous utiliserons httpd d&rsquo;une manière trés simple. Il écoutera seulement
sur le port 80 pour tous les domaines, permettant à acme-client de fonctionner
et redirigera aussi automatiquement les requêtes HTTP vers HTTPS.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># cp /etc/examples/httpd.conf /etc/httpd.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable httpd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start httpd</span>
</span></span></code></pre></div><h3 id="acme-client">acme-client</h3>
<p>Nous utiliserons le fichier exemple par défaut :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># cp /etc/examples/acme-client.conf /etc/acme-client.conf</span>
</span></span></code></pre></div><p>Éditez le fichier <code>/etc/acme-client.conf</code> et changez le dernier bloc <code>domain</code> ;
remplacez <code>example.com</code> et <code>secure.example.com</code> par votre domaine, tels que
<code>cryptpad.kongroo.eu</code> et <code>api.cryptpad.kongroo.eu</code> en tant que nom alternatif.</p>
<p>Pour des raisons pratiques, nous allons remplacer le chemin du certificat
full chain pour avoir <code>hostname.crt</code> au lieu de <code>hostname.fullchain.pem</code>
pour correspondre aux attentes de relayd.</p>
<p>Voici à quoi ressemble ce paragraphe sur mon paramétrage :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">domain</span> <span style="color:#48b685">kongroo.eu</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">alternative</span> <span style="color:#48b685">names</span> { <span style="color:#5bc4bf">api.cryptpad.kongroo.eu</span> <span style="color:#48b685">cryptpad.kongroo.eu</span> <span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">domain</span> <span style="color:#48b685">key</span> <span style="color:#48b685">&#34;/etc/ssl/private/kongroo.eu.key&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">domain</span> <span style="color:#48b685">full</span> <span style="color:#48b685">chain</span> <span style="color:#48b685">certificate</span> <span style="color:#48b685">&#34;/etc/ssl/kongroo.eu.crt&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">sign</span> <span style="color:#48b685">with</span> <span style="color:#48b685">buypass</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><p>Notez qu&rsquo;avec le fichier <a href="https://man.openbsd.org/acme-client.conf" rel="external">acme-client.conf</a> par défaut, vous pouvez
utiliser <em>letsencrypt</em> ou <em>buypass</em> en tant qu&rsquo;autorité de certification.</p>
<p>Vous devriez maintenant être capable de créer vos certificats.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># acme-client kongroo.eu</span>
</span></span></code></pre></div><p>C&rsquo;est fait !</p>
<p>Vous souhaitez que le certificat soit renouvellé automatiquement et que
relayd redémarre après le changement de certificat ? Comme l&rsquo;indique la
page de manuel d&rsquo;acme-client.conf, ajoutez ce qui suit à la crontab de root
en utilisant la commande <code>crontab -e</code> :</p>
<pre tabindex="0"><code class="language-cron" data-lang="cron">~ * * * * acme-client kongroo.eu &amp;&amp; rcctl reload relayd
</code></pre><h3 id="relayd">relayd</h3>
<p>Cette configuration est assez simple : remplacez <code>kongroo.eu</code> par votre
domaine.</p>
<p>Créez un fichier <a href="https://man.openbsd.org/relayd.conf" rel="external">/etc/relayd.conf</a> avec le contenu suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">tcp</span> <span style="color:#48b685">protocol</span> <span style="color:#48b685">&#34;https&#34;</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">tls</span> <span style="color:#48b685">keypair</span> <span style="color:#48b685">kongroo.eu</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">relay</span> <span style="color:#48b685">&#34;https&#34;</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">listen</span> <span style="color:#ef6155">on</span> <span style="color:#48b685">egress</span> <span style="color:#48b685">port</span> <span style="color:#f99b15">443</span> <span style="color:#48b685">tls</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">protocol</span> <span style="color:#48b685">https</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">forward</span> <span style="color:#48b685">to</span> 127.0.0.1 <span style="color:#48b685">port</span> <span style="color:#f99b15">3000</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><p>Activez et démarrez relayd en utilisant rcctl :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable relayd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start relayd</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Vous devriez être capable d&rsquo;atteindre votre instance Cryptpad en utilisant
maintenant votre URL publique. Félicitations !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction du Tutoriel EN → FR &#39;Host your Cryptpad web office suite with OpenBSD&#39; décrivant l&#39;installation, la configuration de la suite web office Cryptpad pour l&#39;utiliser sous OpenBSD]]></summary>
        <published>2020-12-22T23:31:21+01:00</published>
        <updated>2023-05-03T06:30:55+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:7039cc48-be42-da03-a6ca-d8b28bfd6bbc</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/dns-doh-proxy/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : proxy DNS DoH</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DoH" scheme="http://doc.huc.fr.eu.org/fr/tags/doh/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voyons dans cet article comment paramétrer OpenWRT pour qu&rsquo;il puisse
communiquer avec des serveurs DNS sur le protocole 

















<span lang="en">DoH <em>(DNS-over-HTTPS)</em></span>





























































































.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Le protocole DoH, bien que dans l&rsquo;esprit est intéressant, dans la mise
en pratique semble décrié, car n&rsquo;apporte pas toute la confidentialité
nécessaire à laquelle on s&rsquo;attend, ou a besoin. <br>
<em>Faites des recherches pour comprendre la raison, pour laquelle il vaut
mieux préférer <abbr title="DNS-over-TLS">DoT</abbr>
.</em>
<em>Par exemple, vous pouvez lire la <a class="inside" href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#le-probl%c3%a8me-avec-dns-sur-https-doh" title="Lien interne vers l&#39;article : 'Guide du Routeur OpenBSD'">traduction suivante du problème relatif à DoH</a>
.</em></div>

<p>Le but est de :</p>
<ul>
<li>chiffrer le trafic 















<span lang="en">DNS <em>(Domain Name Service)</em></span>































































































 afin d&rsquo;améliorer la confidentialité de celui-ci.</li>
<li>prévenir d&rsquo;une fuite DNS et les détournements de votre trafic 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































</li>
<li>bypasser les restrictions régionales ou celles du 





















<span lang="fr">FAI <em>(Fournisseur d&#39;Accès Internet)</em></span>

























































































.</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Installons les deux paquets nécessaires que sont <strong>https-dns-proxy</strong>, et
<strong>luci-app-https-dns-proxy</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># opkg update</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># opkg install https-dns-proxy luci-app-https-dns-proxy</span>
</span></span></code></pre></div><p>Puis il faut redémarrer le service <strong>rcpd</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># /etc/init.d/rpcd restart</span>
</span></span></code></pre></div><h2 id="configuration">Configuration</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Par défaut, le service est configuré pour utiliser les services des DNS
de Google et de Cloudflare. Néanmoins, il est très facile de changer ce
paramétrage ; sachez qu&rsquo;actuellement, plusieurs autres choix sont possibles
tels que CleanBrowsing, LibreDNS, Cira CA Shield, Adguard, qui proposent
plusieurs listes de protections.</div>

<p>Le service est accessible par le menu &ldquo;<strong>Services → HTTPS DNS Proxy</strong>&rdquo;.</p>
<figure>
    <a href="/images/openwrt/Services-DNS-HTTPS-Proxy.png" title="Service HTTPS DNS Proxy">
    <picture>
        
        <source srcset="/images/openwrt/Services-DNS-HTTPS-Proxy_hu_1af594e727510ed0.webp" type="image/webp">
        
        <img alt="Service HTTPS DNS Proxy" height="402" loading="lazy" src="/images/openwrt/Services-DNS-HTTPS-Proxy_hu_74909c94f3162d63.png" type="image/png" width="512">
    </picture>
    </a>
    <figcaption>Service HTTPS DNS Proxy</figcaption>
</figure>
<hr>
<p>Paramétrez-le de manière à :</p>
<ul>
<li>écouter un serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 choisi par la liste proposée</li>
<li>sur l&rsquo;adresse de bouclage interne localhost, soit sur le protocole 




































<span lang="en">IPv4 <em>(Internet Protocol v4)</em></span>










































































,
soit sur 





































<span lang="en">IPv6 <em>(Internet Protocol v6)</em></span>









































































, ou les deux</li>
<li>et affecter un port de service sur lequel écouter.</li>
</ul>
<p>Puis, appuyez sur le bouton :</p>
<ul>
<li><strong>[ SAVE &amp; APPLY ]</strong> en bas de page</li>
<li>puis, dans la section <strong>Service Status</strong>, sur celui nommé <strong>[ RELOAD ]</strong></li>
</ul>
<p>Ainsi le service sera actif, et prendra en charge la communication vers
les serveurs 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 <abbr lang="en" title="DNS-over-HTTPS">DoH</abbr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 configurés.</p>
<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si vous avez le service DHCP activé, sachez qu&rsquo;il se répercute dans la
section <strong>DNS forwardings</strong> du menu &ldquo;<strong>Network → DNS and DHCP</strong>&rdquo;.</div>

<h3 id="configuration-cli">Configuration CLI</h3>
<p>Il est possible de configurer le service par le biais de la console shell :</p>
<p>Voici l&rsquo;exemple que donne la communauté OpenWRT :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># Configure DoH provider</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">while</span> uci -q delete https-dns-proxy.@https-dns-proxy<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">do</span> :; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>uci set https-dns-proxy.dns<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https-dns-proxy&#34;</span>
</span></span><span style="display:flex;"><span>uci set https-dns-proxy.dns.bootstrap_dns<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;8.8.8.8,8.8.4.4&#34;</span>
</span></span><span style="display:flex;"><span>uci set https-dns-proxy.dns.resolver_url<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://dns.google/dns-query&#34;</span>
</span></span><span style="display:flex;"><span>uci set https-dns-proxy.dns.listen_addr<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span>uci set https-dns-proxy.dns.listen_port<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;5053&#34;</span>
</span></span><span style="display:flex;"><span>uci commit https-dns-proxy
</span></span><span style="display:flex;"><span>/etc/init.d/https-dns-proxy restart
</span></span></code></pre></div><p>Le paramétrage présenté est pour les serveurs 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 de Google…</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://openwrt.org/docs/guide-user/services/dns/doh_dnsmasq_https-dns-proxy" rel="external">https://openwrt.org/docs/guide-user/services/dns/doh_dnsmasq_https-dns-proxy</a></li>
</ul>
<hr>
<p>Mais peut-être que vous préférerez utiliser 




















<span lang="en">DoT <em>(DNS-over-TCP)</em></span>


























































































 ; si oui, lisez :

<a class="inside" href="/fr/sys/openwrt/unbound-dot/" title="Lien interne vers l&#39;article : 'OpenWRT &#43; Unbound : utiliser le protocole DoT '">OpenWRT &#43; Unbound : utiliser le protocole DoT </a>

</p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment utiliser OpenWRT pour qu&#39;il fasse proxy vers des DNS sur le protocole DoH]]></summary>
        <published>2020-12-22T10:22:49+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:41b758f6-3e50-af95-72d5-5bb90d41826a</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-image-webp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx gère les images au format Webp</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="image" scheme="http://doc.huc.fr.eu.org/fr/tags/image/" />
        <category term="webp" scheme="http://doc.huc.fr.eu.org/fr/tags/webp/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ici, il n&rsquo;est pas question de demander au serveur web nginx de modifier/créer
à la volée des images au format WebP.</p>
<p><em>Pour ceux qui ne savent pas ce qu&rsquo;est le format WebP, sachez que c&rsquo;est
un conteneur d&rsquo;image matricielle, développé par… Google. Il permet de
faire d&rsquo;obtenir des images plus légères, qu&rsquo;elles ne le seraient au
format JPEG. cf: la section <a href="/fr/web/nginx/nginx-image-webp/#Documentation">Documentation</a> ci-dessous !</em></p>
<h2 id="installation">Installation</h2>
<p>Bref, cela nécessite d&rsquo;installer sur votre système d&rsquo;exploitation la
bibliothèque nécessaire :</p>
<ul>
<li>sous Linux : le paquet <strong>webp</strong></li>
<li>sous OpenBSD : le paquet <strong>libwebp</strong></li>
</ul>
<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">ImageMagick est aussi capable de convertir une image au format WebP :
<code>:$ convert &quot;${file}&quot; &quot;${file}.webp&quot;</code></div>

<h2 id="utilisation">Utilisation</h2>
<p>Pour transformer une image jpg, png, voire tiff au format, il suffit d&rsquo;appeler
la bibliothèque <strong>cwebp</strong>, très simplement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cwebp -m <span style="color:#f99b15">0</span> -mt <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">image</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">image</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span></code></pre></div><p>Quant aux images gif, elles sont converties grâce à la bibliothèque <strong>gif2wepb</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>gif2webp -m <span style="color:#f99b15">0</span> -mt <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">image</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">image</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span></code></pre></div><p>Veuillez lire le manpage correspondant pour connaître les différentes options
de la bibliothèque :</p>
<ul>
<li><code>:$ man cwebp</code></li>
<li><code>:$ man gif2webp</code></li>
</ul>
<hr>
<p>Voici le code que j&rsquo;utilise personnellement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>_webp<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> ! -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>file -b <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;GIF&#39;</span>*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                gif2webp -m <span style="color:#f99b15">0</span> -mt <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span><span style="display:flex;"><span>            ;;
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;JPEG&#39;</span>|<span style="color:#48b685">&#39;PNG&#39;</span>|<span style="color:#48b685">&#39;TIFF&#39;</span>*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                cwebp -exact -lossless -m <span style="color:#f99b15">0</span> -mt -progress <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span><span style="display:flex;"><span>            ;;
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><p>Que fait ce code ?</p>
<p>Dans les faits, il teste :</p>
<ol>
<li>l&rsquo;existence du fichier ayant l&rsquo;extension de fichier <code>.webp</code></li>
<li>puis détermine le type du fichier et appelle la bonne bibliothèque selon
le format détecté.</li>
</ol>
<p>Par soucis de simplicité et de lecture, il génére une image au format webp,
portant l&rsquo;extension <code>.webp</code>, ajouté à son nom de fichier originel, tel que
<strong>image.jpg.webp</strong>, pour l&rsquo;exemple.<br>
<em>Tu verras, toi mon lecteur, que cela nous facilite la configuration de
nginx, par la suite.</em></p>
<p>Ensuite, je parcoure un répertoire d&rsquo;image par le biais de la fonction
<code>find</code>, qui appelle la fonction <code>_webp</code> déclarée ci-dessus, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>find . -type f -a <span style="color:#f99b15">\(</span> <span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span>        -name <span style="color:#48b685">&#34;*.gif&#34;</span> -o -name <span style="color:#48b685">&#39;*.jpg&#39;</span> -o -name <span style="color:#48b685">&#39;*.jpeg&#39;</span> -o -name <span style="color:#48b685">&#39;*.png&#39;</span> -o -name <span style="color:#48b685">&#39;*.tiff&#39;</span> <span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span>        <span style="color:#f99b15">\)</span> | <span style="color:#815ba4">while</span> read -r file; <span style="color:#815ba4">do</span> _webp; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><hr>
<p>Voici le script shell que j&rsquo;utilise :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span>clear
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Author: Stéphane HUC</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mail: devs@stephane-huc.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># License: Public Domain</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Git:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Date: 2020/10/03</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Convert to webp images</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#ROOT=&#34;$(dirname &#34;$(readlink -f -- &#34;$0&#34;)&#34;)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_webp<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> ! -f <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>file -b <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;GIF&#39;</span>*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                gif2webp -m <span style="color:#f99b15">0</span> -mt <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span><span style="display:flex;"><span>            ;;
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;JPEG&#39;</span>|<span style="color:#48b685">&#39;PNG&#39;</span>|<span style="color:#48b685">&#39;TIFF&#39;</span>*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                cwebp -exact -lossless -m <span style="color:#f99b15">0</span> -mt -progress <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">.webp&#34;</span>
</span></span><span style="display:flex;"><span>            ;;
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>main<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    find . -type f -a <span style="color:#f99b15">\(</span> <span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span>        -name <span style="color:#48b685">&#34;*.gif&#34;</span> -o -name <span style="color:#48b685">&#39;*.jpg&#39;</span> -o -name <span style="color:#48b685">&#39;*.jpeg&#39;</span> -o -name <span style="color:#48b685">&#39;*.png&#39;</span> -o -name <span style="color:#48b685">&#39;*.tiff&#39;</span> <span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span>        <span style="color:#f99b15">\)</span> | <span style="color:#815ba4">while</span> read -r file; <span style="color:#815ba4">do</span> _webp; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">########################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>main
</span></span></code></pre></div><p><em>Celui-ci est aisément modifiable pour l&rsquo;utiliser sous tout autre shell.</em></p>
<hr>
<p>De deux manières l&rsquo;une, j&rsquo;utilise ce script soit en l&rsquo;appelant individuellement,
soit par le biais de mon script de déploiement de mes fichiers vers le
serveur web.</p>
<p>Ainsi, en sus des images aux formats originels, j&rsquo;y dépose celles au format
webp. ;-)</p>
<h2 id="configuration">Configuration</h2>
<p>Modifions la configuration de nginx, afin de lui signifier que quand il
est demandé des images au format jpeg|gif|png|tiff, il essaye de diffuser
celles au format webp, si elles existent.</p>
<hr>
<p>⇒ Dans le contexte <code>http</code> du serveur, ajoutons une <code>map</code> afin de déclarer
une variable <code>$webp_suffix</code> qui nous permettra de reconnaître une image
ayant l&rsquo;extension <code>.webp</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_accept</span> <span style="color:#ef6155">$webp_suffix</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">webp_suffix</span> <span style="color:#48b685">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&#34;~*webp&#34;</span> <span style="color:#48b685">&#34;.webp&#34;</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>⇒ Le script suivant est à inclure dans le contexte de la déclaration <code>server</code>
de votre configuration d&rsquo;hôte virtuel.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.(jpe?g|gif|png|tiff)$</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">access_log</span>        <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Cache-Control</span> <span style="color:#48b685">&#34;public,</span> <span style="color:#48b685">must-revalidate,</span> <span style="color:#48b685">proxy-revalidate&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Pragma</span> <span style="color:#48b685">public</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">expires</span>           <span style="color:#48b685">max</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">log_not_found</span> <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">try_files</span> <span style="color:#ef6155">$uri$webp_suffix</span> <span style="color:#ef6155">$uri</span> =<span style="color:#f99b15">404</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.(gif|jpe?g|png|tiff).webp</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">access_log</span>        <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Cache-Control</span> <span style="color:#48b685">&#34;public,</span> <span style="color:#48b685">must-revalidate,</span> <span style="color:#48b685">proxy-revalidate&#34;</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Content-Type</span> <span style="color:#48b685">image/webp</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Pragma</span> <span style="color:#48b685">public</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">image/webp</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">expires</span>           <span style="color:#48b685">max</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># normalement, non nécessaire car déclaré dans les types mimes reconnus par nginx
</span></span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">types</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">image/webp</span> <span style="color:#48b685">webp</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Ce que fait cette configuration ?</p>
<ol>
<li>Lorsqu&rsquo;un appel est fait vers une image, au format sus-mentionné :
<ul>
<li>aucune inscription au journal n&rsquo;est faite</li>
<li>envoie des entêtes HTTP nécessaires pour une bonne &ldquo;publication&rdquo;
par le serveur vers le client.</li>
<li>essaie d&rsquo;envoyer l&rsquo;image portant l&rsquo;extension <code>.webp</code>, suffixé au nom
de l&rsquo;image appelée, sinon retourne logiquement une erreur 404. <br>
<em>remarque l&rsquo;utilisation de la variable <code>$webp_suffix</code> à la ligne 13</em>.</li>
</ul>
</li>
<li>L&rsquo;appel à une image portant l&rsquo;extension <code>.webp</code> :
<ul>
<li>n&rsquo;est pas journalisé</li>
<li>envoie les entêtes HTTP nécessaires</li>
<li>définit correctement le bon type mime.</li>
</ul>
</li>
</ol>
<hr>
<p>Et, voilà !!!</p>
<p>Reste plus qu&rsquo;à tester votre configuration avec nginx et redémarrer le service
correspondant - <em>par exemple, pour OpenBSD</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# nginx -t
</span></span><span style="display:flex;"><span>:# rcctl restart nginx
</span></span></code></pre></div><h2 id="html">HTML</h2>
<p>Pour finir, modifiez votre code HTML à-propos de la gestion des images,
tel que, par exemple pour une image jpeg, à minima :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">picture</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">source</span> <span style="color:#06b6ef">srcset</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/img/{{ $img }}.jpg.webp&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/webp&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">img</span> <span style="color:#06b6ef">alt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;texte&#34;</span> <span style="color:#06b6ef">src</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/img/{{ $img }}.jpg&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/jpeg&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">picture</span>&gt;
</span></span></code></pre></div><p>Ce qui permettra aux clients web qui supportent le format webp de demander
l&rsquo;affichage de ce format en lieu et place…</p>
<h3 id="essai">Essai</h3>
<p>Test avec mon Logo :</p>
<figure>
    <a href="/images/logo.png" title="Logo">
    <picture>
        
        <source srcset="/images/logo_hu_c9e055de1824af3f.webp" type="image/webp">
        
        <img alt="Logo" height="128" loading="lazy" src="/images/logo.png" type="image/png" width="128">
    </picture>
    </a>
    <figcaption>Logo</figcaption>
</figure>
<p>Ainsi, selon le support du client web, vous recevrez soit le format WebP,
sinon le fichier &ldquo;source&rdquo; png…</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/WebP" title="Article Wikipédia : WebP">WebP <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://developers.google.com/speed/webp" rel="external">A new image format for the Web</a> : site officiel</li>
<li>le site caniuse.com : <a href="https://caniuse.com/webp" rel="external">https://caniuse.com/webp</a></li>
</ul>
]]></content>
        <summary type="html"><![CDATA[Configurer Nginx pour qu&#39;il diffuse les images au format WebP, au lieu de…]]></summary>
        <published>2020-12-21T12:57:24+01:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8f82a0e0-3d93-22a9-7312-89c7378d1726</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Guide du Routeur OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Guide" scheme="http://doc.huc.fr.eu.org/fr/tags/guide/" />
        <category term="Routeur" scheme="http://doc.huc.fr.eu.org/fr/tags/routeur/" />
        <content type="html"><![CDATA[<h1 id="guide-du-routeur-openbsd">Guide du Routeur OpenBSD</h1>
<p>Pare-feu segmentant un réseau, avec DHCP, DNS (Unbound), blocage de domaine
et bien plus encore.</p>
<ul>
<li>OpenBSD: 6.9 · Publié : 2020-11-05 · Mis-à-jour : 2021-07-21 · Version : 1.9.4</li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>Dans ce guide, nous verrons comment nous pouvons utiliser du matériel
&ldquo;bas de gamme&rdquo; bon marché pour construire un routeur OpenBSD terrible
avec des capacités de pare-feu, des réseaux locaux segmentés, du DNS
avec blocage de noms de domaines, du DHCP et bien plus.</p>
<p>Nous commencerons par paramétrer les segments réseaux (LAN) par trois
réseaux séparés, un pour les adultes à la maison, un pour les enfants
et un pour les serveurs face à Internet (comme une <a href="https://fr.wikipedia.org/wiki/Zone_d%C3%A9militaris%C3%A9e_(informatique)" rel="external">DMZ</a>),
tel qu&rsquo;un serveur web ou serveur mail privé.
Nous chercherons à voir comment nous pouvons utiliser DNS pour bloquer
les publicités, le porno, et d&rsquo;autres sites sur Internet. Le routeur OpenBSD
peut aussi être utilisé dans de petites ou moyennes entreprises.</p>
<h2 id="conventions-typographiques-utilisées-dans-ce-guide">Conventions typographiques utilisées dans ce guide</h2>
<ul>
<li>La police à <code>largeur fixe</code> (mono-espacement) est utilisée pour les commandes
en console, les noms de fichiers et leurs chemins, les paramètres de
configuration, etc…</li>
<li>Les commandes en console qui doivent être tapées en tant qu&rsquo;utilisateur
<code>root</code> sont préfixées du symbole dièse <code>#</code> et la commande apparaît en
<strong>gras</strong> dans le texte.</li>
<li>Les commandes en console qui doivent être tapées en tant qu&rsquo;utilisateur
normal sont préfixées du symbole dollar <code>$</code> et la commande apparaît en
<strong>gras</strong> dans le texte.</li>
</ul>
<h2 id="pourquoi-un-pare-feu-">Pourquoi un pare-feu ?</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Actuellement ce guide aborde IPv4, car la plupart des personnes
n&rsquo;utilisent pas IPv6 et beaucoup de FAI - <em>Fournisseur d&rsquo;Accès à Internet</em> -
utilisent seulement IPv4, mais IPv6 est planifié dans le contexte d&rsquo;une
future mise à jour de ce guide.</div>

<p>Peu importe comment vous vous connectez à Internet depuis votre domicile
ou votre bureau, vous avez besoin d&rsquo;un vrai pare-feu entre vous et le modem
ou routeur que vous fourni votre FAI.</p>
<p>Il est très rare que les modems ou routeurs grand public reçoivent des
mises à jour du micrologiciel et sont souvent vulnérables aux attaques
réseau qui transforment ces appareils en <a href="https://fr.wikipedia.org/wiki/Botnet" rel="external">Botnet</a>,
tel que le fait le <a href="https://fr.wikipedia.org/wiki/Mirai_(logiciel_malveillant)" rel="external">logiciel malveillant Mirai</a>.
De nombreux modems et routeurs grand public sont à blâmer à propos de
certaines <a href="https://fr.wikipedia.org/wiki/Attaque_par_d%C3%A9ni_de_service" rel="external">attaques par déni de service de grande envergure (DOS)</a></p>
<p>Un pare-feu entre vous et le modem ou routeur de votre FAI ne peut pas
protéger votre dispositif modem ou routeur contre de telles attaques,
mais il peut protéger vos ordinateurs et dispositifs à l&rsquo;intérieur du
réseau, et il peut vous aider à surveiller et contrôler le trafic qui
arrive vers votre réseau local et qui en part.</p>
<p>Sans un pare-feu entre votre réseau local et le modem ou routeur du FAI,
vous pouvez considérer basiquement que votre porte est grande ouverte,
comme laisser grande ouverte la porte de votre maison, ainsi vous ne pouvez
pas faire confiance en l&rsquo;équipement de votre FAI.</p>
<p>C&rsquo;est toujours réellement une bonne idée de mettre un vrai pare-feu entre
votre réseau local et Internet, et avec OpenBSD vous avez une solution très
solide.</p>
<h2 id="le-matériel">Le Matériel</h2>
<p>Vous n&rsquo;avez pas besoin d&rsquo;acheter du matériel cher pour avoir un routeur
et un pare-feu efficaces pour votre maison ou votre bureau.
Même avec du matériel &ldquo;bas de gamme&rdquo; bon marché, vous pouvez avoir une
solution très solide.</p>
<p>J&rsquo;ai créé de multiples solutions avec la carte-mère
<a href="https://www.asrock.com/mb/Intel/Q1900DC-ITX/" rel="external">ASRock Q1900DC-ITX</a> qui est
fournie avec un processeur Intel Celeron Quadri-Cœur.</p>
<figure>
    <a href="/images/unixsheikh.com/asrock-q1900dc-itx.png" title="ASRock Q1900DC-ITX">
    <picture>
        
        <source srcset="/images/unixsheikh.com/asrock-q1900dc-itx_hu_f0044d031839a37e.webp" type="image/webp">
        
        <img alt="ASRock Q1900DC-ITX" height="407" loading="lazy" src="/images/unixsheikh.com/asrock-q1900dc-itx.png" type="image/png" width="600">
    </picture>
    </a>
    <figcaption>ASRock Q1900DC-ITX</figcaption>
</figure>
<p>Je l&rsquo;admet, c&rsquo;est une carte-mère assez &ldquo;pourrie&rdquo;, mais elle fait le boulot
et j&rsquo;ai de nombreuses solutions très solides qui fonctionnent depuis de
nombreuses années sur des réseaux Gigabit avec saturation complète et le
pare-feu, DNS, faisant des &ldquo;heures supplémentaires&rdquo; et où le CPU ne chauffe
pas.</p>
<p>La carte-mère ASRock Q1900DC-ITX a pour avantage qu&rsquo;elle est fournie
avec une prise jack DC-In (entrée électrique) qui est compatible avec
un adaptateur électrique 9-19V, ce qui la rend très économe en énergie.
Malheureusement, la carte-mère ASRock Q1900DC-ITX n&rsquo;est plus fabriquée,
mais comme je l&rsquo;utilise juste comme exemple ;
j&rsquo;ai utilisé de nombreuses autres carte-mères bon marché tout aussi bien.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Beaucoup d&rsquo;autres carte-mères faites par d&rsquo;autres fabricants
consommant peu peuvent être aussi bien utilisées, tel le fameux <a href="https://www.pcengines.ch/apu2.htm" rel="external">APU2</a>.</div>

<p>J&rsquo;ai aussi utilisé l&rsquo;ASRock Q1900-ITX (qui est fournie sans la prise jack
DC-In) combinée à un PicoPSU.</p>
<figure>
    <a href="/images/unixsheikh.com/picopsu.png" title="PicoPSU">
    <picture>
        
        <source srcset="/images/unixsheikh.com/picopsu_hu_609d0d0705dd62f6.webp" type="image/webp">
        
        <img alt="PicoPSU" height="284" loading="lazy" src="/images/unixsheikh.com/picopsu.png" type="image/png" width="314">
    </picture>
    </a>
    <figcaption>PicoPSU</figcaption>
</figure>
<p>Vous pouvez trouvez différentes marques et version du PicoPSU, certains
sont de meilleurs qualités que d&rsquo;autres. J&rsquo;ai deux marques différentes,
l&rsquo;original et une copie moins chère, toutes deux sont très performants et
permettent d&rsquo;économiser par mal d&rsquo;énergie contrairement à une alimentation
normale.</p>
<p>Enfin, j&rsquo;utilise une carte réseau quadruple port Intel bon marché, trouvé
sur Ebay, tel que celle-ci :</p>
<figure>
    <a href="/images/unixsheikh.com/intel-quad-nic.png" title="Quad NIC Intel">
    <picture>
        
        <source srcset="/images/unixsheikh.com/intel-quad-nic_hu_b0883f95cbee7a05.webp" type="image/webp">
        
        <img alt="Quad NIC Intel" height="215" loading="lazy" src="/images/unixsheikh.com/intel-quad-nic.png" type="image/png" width="368">
    </picture>
    </a>
    <figcaption>Quad NIC Intel</figcaption>
</figure>
<p>Je sais, il est préférable d&rsquo;utiliser du matériel de qualité, spécifiquement
sur un réseau dont vous avez à prendre soin, mais ce tutoriel est relatif
au fait de comment vous pouvez vous en sortir en utilisant du matériel
bon marché tout en ayant un produit extrêmement utile qui continue à bien
vous servir pendant de nombreuses années - du moins, telle est mon expérience.</p>
<p>Je vous recommande de chercher une carte mini-ITX dont le matériel est
<a href="https://www.openbsd.org/amd64.html" rel="external">pris en charge par OpenBSD</a>, tel qu&rsquo;un
CPU Intel Celeron ou Intel i3. Ces cartes-mères sont typiquement peu chères,
peu gourmandes d&rsquo;énergie, et ne prennent pas beaucoup de place.
Je ne recommande pas l&rsquo;utilisation d&rsquo;un CPU Intel Atom si vous avez un réseau
Gigabit, car il ne peut pas gérer la quantité de trafic.</p>
<p>Vous pourriez également avoir besoin de quelques commutateurs Gigabit
bon marché pour segmenter votre réseau local, au moins si vous avez plus
d&rsquo;un ordinateur connecté sur le même LAN :)</p>
<h2 id="pourquoi-openbsd-">Pourquoi OpenBSD ?</h2>
<p>En vérité, vous pouvez avoir le même paramétrage avec une autre saveur
BSD ou une des différentes <a href="https://fr.wikipedia.org/wiki/Distribution_Linux" rel="external">distributions Linux</a>,
mais <a href="https://www.openbsd.org/" rel="external">OpenBSD</a> est spécifiquement très bien
adapté et conçu pour ce genre de tâche.
Non seulement il est livré avec tous les logiciels nécessaires dans
l&rsquo;installation de base, mais il offre également une sécurité nettement
supérieure, et des tonnes de mesure d&rsquo;atténuation améliorées déjà intégrées
dans le système d&rsquo;exploitation.
Je <a href="https://www.unixsheikh.com/articles/openbsd-is-fantastic.html" rel="external">recommande chaudement</a>
OpenBSD plutôt que tout autre système d&rsquo;exploitation pour ce genre de
tâches.</p>
<p>Ce guide ne vous montre pas comment installer OpenBSD.
Si vous ne savez pas faire, je vous recommande de faire fonctionner une
machine virtuelle avant ou de voir si vous avez du matériel inutilisé et
pris en charge avec lequel vous pourriez tester.
OpenBSD est un des systèmes d&rsquo;exploitations des plus faciles et rapides à
installer.
N&rsquo;ayez pas peur de l&rsquo;approche sans GUI (interface utilisateur) ; une fois
que vous l&rsquo;avez essayé, vous apprécierez vraiment sa simplicité.
Dans le doute, utilisez les paramètres par défaut.</p>
<p>Avant de commencer ce voyage, assurez-vous de consulter la documentation
d&rsquo;OpenBSD !
Non seulement, chaque chose est très bien documentée, mais vous trouverez
très probablement toutes les réponses dont vous avez besoin.
Lisez la <a href="https://www.openbsd.org/faq/index.html" rel="external">FAQ OpenBSD</a>,
regardez les différentes <a href="https://man.openbsd.org/" rel="external">pages de manuels</a> à
propos des différents logiciels que nous allons utiliser.</p>
<p>Un autre endroit vraiment utile où trouver des informations générales à
propos d&rsquo;OpenBSD sont les <a href="https://marc.info/?l=openbsd-misc" rel="external">archives des listes de diffusions d&rsquo;OpenBSD</a>.
Aussi assurez-vous de rester à jour des informations pertinentes en
souscrivant à la liste de diffusion des <a href="https://www.openbsd.org/mail.html" rel="external">Annonces et avis de sécurité</a>.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Veuillez considérer de <a href="https://www.openbsd.org/donations.html" rel="external">soutenir OpenBSD</a> !
Même si vous n&rsquo;utilisez pas quotidiennement OpenBSD, vous
utilisez peut-être déjà <a href="https://www.openssh.com/" rel="external">OpenSSH</a> sur Linux,
alors vous utilisez vraiment un logiciel du projet OpenBSD.
Considérez de faire un petit, mais régulier, don pour soutenir le développement
de tous les excellents logiciels que les développeurs d&rsquo;OpenBSD font.</div>

<h2 id="le-réseau">Le réseau</h2>
<p>Un routeur est basiquement un dispositif qui régule le trafic réseau entre
deux ou plusieurs réseaux séparés.
Le routeur garantira que le trafic réseau à destination du réseau local
ne circule pas sur Internet, et que le trafic sur Internet, qui n&rsquo;est pas
à destination de votre réseau local, reste sur Internet.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Un routeur est parfois aussi appelé passerelle, ce qui est généralement
le terme, mais en vérité une véritable passerelle joint des systèmes
différents, alors qu&rsquo;un routeur joint des réseaux similaires.
Un exemple de passerelle serait un dispositif qui joint un réseau PC avec
un réseau télécom.</div>

<p>Dans ce tutoriel, nous construirons un routeur et nous avons 4 réseaux
de même type à faire travailler ensemble.
L&rsquo;un est Internet, et les trois autres sont segmentés intentionnellement
en réseaux locaux (LAN).
Certaines personnes préfèrent travailler avec des LAN virtuels (VLAN),
mais dans ce tutoriel nous utiliserons une interface réseau 4 ports,
telle que vue sur l&rsquo;illustration ci-dessus.
Vous pouvez arriver au même résultat en utilisant de multiples cartes réseau
à port unique, si vous préférez ; vous devez juste vous assurez d&rsquo;avoir
assez de place et de slot PCI libre sur la carte-mère.
Vous pouvez aussi utiliser le port Ethernet de la carte-mère, mais cela
dépend du pilote et de la prise en charge du dispositif.
Je n&rsquo;ai pas de problème à utiliser un contrôleur Ethernet Gigabit PCI Realtek
qui est fourni avec beaucoup de carte-mères, bien que je recommande plutôt Intel.</p>
<p>Bien sûr, vous n&rsquo;avez pas à segmenter le réseau en de nombreuses parties
si vous n&rsquo;avez pas besoin de cela, et il serait très facile de changer les
paramètres de ce guide, mais j&rsquo;ai décidé d&rsquo;utiliser cette approche avant
de vous montrer comment vous pouvez protéger vos enfants en segmentant
leur réseau dans un LAN séparé qui permet non seulement de bloquer la
publicité et la pornographie grâce au blocage des DNS (tous les segments
en bénéficient), mais vous pouvez même mettre sur une liste blanche les
partie de l&rsquo;Internet auxquelles vous voulez qu&rsquo;ils aient accès.
La dernière partie à propos des listes blanches est difficile et n&rsquo;est
généralement pas recommandé à moins que vos enfants aient besoin d&rsquo;un
accès très limité, mais c&rsquo;est faisable avec un peu de travail, et le guide
va vous montrer une façon de faire.</p>
<p>Ceci est une illustration du réseau que nous allons paramétrer :</p>
<pre>
                       Internet
                          |
                    xxx.xxx.xxx.xxx
                    Modem FAI (WAN)
                      10.24.0.23
                          |
                       OpenBSD
                      10.24.0.50
                  (routeur/parefeu)
                          |
     ┌────────────────────+────────────────────┐
     |                    |                    |
    NIC1                 NIC2                 NIC3 (DMZ)
192.168.1.1          192.168.2.1          192.168.3.1
LAN1 switch          LAN2 switch          LAN3 switch
     |                    |                    |
     └─ 192.168.1.x       ├─ 192.168.2.x       └─ 192.168.3.2
        PC Adultes        |  PC1 Enfant            Public web server
                          |
                          └─ 192.168.2.x
                             PC2 Enfant
</pre>
<p>Les adresses IP qui commencent par 10.24.0 sont n&rsquo;importe quelle adresse
IP que le routeur ou modem de votre FAI vous donne ; elles peuvent être
très différentes. Les adresses IP commençant par 192.168 sont les adresses
IP que nous allons utiliser dans ce guide pour notre réseau local (LAN).</p>
<p>Ce guide ne s&rsquo;occupe en aucun cas de connectivité Wifi.
Les micrologiciels des puces sans fil sont notoirement bogués et exploitables ;
je vous recommande de n&rsquo;utiliser aucun type de connectivité sans fil, si
vous pouvez vous en passer.
Si vous avez besoin de la connectivité sans fil, je recommande chaudement
que vous désactiviez l&rsquo;accès Wifi du modem ou routeur du FAI (si possible),
et ensuite d&rsquo;acheter le meilleur routeur Wifi que vous pouvez trouver puis
de le mettre derrière le pare-feu dans un segment isolé.
Ainsi, si jamais votre appareil sans fil est compromis, vous pourrez mieux
contrôler le résultat et limiter les dégâts.
Vous pouvez en outre configurer le routeur sans fil de telle sorte que
tout appareil, qui y est connecté, dispose de ses propres adresses IP
qui passent directement par le routeur sans fil, tout en bloquant le
trafic provenant du routeur sans fil lui-même.
De cette façon, vous pouvez empêcher le routeur sans fil de &ldquo;téléphoner à la maison&rdquo;.
Vous pouvez aussi avoir un adaptateur Wifi supporté par OpenBSD et que
votre routeur OpenBSD agisse en tant que point d&rsquo;accès, toutefois je préfère
de beaucoup segmenter la partie Wifi soit par un routeur sans fil séparé,
soit par une autre machine OpenBSD servant de point d&rsquo;accès Wifi derrière
le pare-feu lui-même.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Actuellement, autant que je le sache, aucun des pilotes Wifi d'
OpenBSD ne posent pas encore de problèmes.</div>

<h3 id="paramétrer-le-réseau">Paramétrer le réseau</h3>
<p>La première chose que nous allons paramétrer sont les différentes interfaces
réseaux de notre routeur OpenBSD.
Sur ma machine, j&rsquo;ai désactivé l&rsquo;interface réseau qui est livré avec la
carte-mère via le BIOS, et je n&rsquo;utilise que l&rsquo;interface réseau 4 ports d&rsquo;Intel.</p>
<p>Si vous suivez ce tutoriel et que vous souhaitez seulement un pare-feu
basique alors vous avez au moins besoin de deux interfaces réseaux séparées.</p>
<p>Avant de commencer, assurez-vous de lire et de comprendre les différentes
options de la page de manuel <a href="https://man.openbsd.org/hostname.if" rel="external">hostname.if</a>.
Prenez aussi le temps de lire la section réseau de la <a href="https://www.openbsd.org/faq/faq6.html" rel="external">FAQ d&rsquo;OpenBSD</a>.</p>
<p>Puisque j&rsquo;utilise Intel, le pilote <a href="https://man.openbsd.org/em" rel="external">em</a> est
celui qu&rsquo;OpenBSD charge sur chacun des ports de cette interface réseau,
qui sont listés comme étant des cartes séparées.
Cela signifie que chaque carte est listée en tant qu&rsquo;<code>emX</code> où X est le
numéro actuel du port de la carte.</p>
<p><code>dmesg</code> liste ma carte réseau avec 4 ports de telle manière :</p>
<pre tabindex="0"><code># dmesg
em0 at pci2 dev 0 function 0 &#34;Intel I350&#34; rev 0x01: msi, address a0:36:9f:a1:66:b8
em1 at pci2 dev 0 function 1 &#34;Intel I350&#34; rev 0x01: msi, address a0:36:9f:a1:66:b9
em2 at pci2 dev 0 function 2 &#34;Intel I350&#34; rev 0x01: msi, address a0:36:9f:a1:66:ba
em3 at pci2 dev 0 function 3 &#34;Intel I350&#34; rev 0x01: msi, address a0:36:9f:a1:66:bb
</code></pre><p>Ce qui montre que ma carte est reconnu comme étant une Intel I350-T4 PCI Express Quad Port Gigabit NIC.</p>
<p>Il faut ensuite déterminer quel est le port correspondant physiquement au
numéro indiqué ci-dessus.
Vous pouvez le faire en connectant manuellement un câble Ethernet, connecté
sur un commutateur actif, un modem ou un routeur, sur chacun des ports,
un à la fois, afin de voir quel port est activé et le noter ensuite quelque part.</p>
<p>Vous pouvez vérifier le statuts d&rsquo;activité avec la commande <code>ifconfig</code>.
Un port sans câble Ethernet sera listé comme ayant le champ <code>status</code> notifié
<code>no carrier</code> alors qu&rsquo;un port avec un câble attaché sera listé en <code>active</code>.
Tel que :</p>
<pre tabindex="0"><code># ifconfig
em1: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        lladdr a0:36:9f:a1:66:b9
        index 2 priority 0 llprio 3
        media: Ethernet autoselect (none)
        status: active
em2: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        lladdr a0:36:9f:a1:66:ba
        index 3 priority 0 llprio 3
        media: Ethernet autoselect (none)
        status: no carrier
</code></pre><p>Nous allons utiliser le port <code>em0</code> afin de le connecter au modem ou routeur
de votre FAI, vers Internet.
Dans mon cas, j&rsquo;ai une adresse IP publique fournie par mon FAI ; vous en
aurez besoin si vous voulez faire fonctionner un serveur web depuis votre
maison, mais si ce n&rsquo;est pas le cas, vous n&rsquo;en avez pas besoin, ainsi vous
pouvez paramétrer la carte par DHCP.</p>
<p>Dans mon cas, j&rsquo;ai besoin de spécifier une adresse IP fixe pour <code>em0</code> qui
recevra alors le trafic redirigé depuis mon FAI vers mon adresse IP publique.
Pour faire cela, je paramètre <code>em0</code> avec l&rsquo;information suivante :</p>
<pre tabindex="0"><code># echo &#39;inet 10.24.0.50 255.255.254.0 NONE&#39; &gt; /etc/hostname.em0
</code></pre><p>Si vous n&rsquo;avez pas besoin d&rsquo;une adresse IP publique et que votre adresse
IP est obtenue par votre FAI via DHCP, alors écrivez juste <code>dhcp</code> à la place :</p>
<pre tabindex="0"><code># echo &#39;dhcp&#39; &gt; /etc/hostname.em0
</code></pre><p>Ensuite, je paramètre le reste des ports de l&rsquo;interface réseau avec leurs
adresses IP, tel que je l&rsquo;ai précédemment illustré.</p>
<pre tabindex="0"><code># echo &#39;inet 192.168.1.1 255.255.254.0 NONE&#39; &gt; /etc/hostname.em1
# echo &#39;inet 192.168.2.1 255.255.254.0 NONE&#39; &gt; /etc/hostname.em2
# echo &#39;inet 192.168.3.1 255.255.254.0 NONE&#39; &gt; /etc/hostname.em3
</code></pre><p>Regardez la page du manuel <a href="https://man.openbsd.org/hostname.if" rel="external">hostname.if</a>
pour avoir plus d&rsquo;informations.</p>
<p>Ensuite, j&rsquo;ai besoin de paramétrer l&rsquo;IP de la passerelle du FAI.
Selon le paramétrage de votre FAI, cela peut être une autre adresse IP que
celle du modem ou routeur du FAI.
Si vous n&rsquo;ajoutez pas le fichier <code>/etc/mygate</code> alors aucune passerelle par
défaut ne sera ajouté à la <a href="https://fr.wikipedia.org/wiki/Table_de_routage" rel="external">table de routage</a>.
Vous n&rsquo;avez pas besoin de <code>/etc/mygate</code> si votre IP est fournie par le
modem ou routeur de votre FAI via DHCP.
Si vous utilisez la directive <code>dhcp</code> dans n&rsquo;importe quel fichier <code>hostname.ifX</code>
alors l&rsquo;entrée dans le fichier <code>/etc/mygate</code> sera ignorée.
Cela est parce que la carte obtient son adresse IP depuis un serveur DHCP
qui fournira aussi l&rsquo;information de routage vers la passerelle.</p>
<p>Enfin, mais pas des moindres, nous avons besoin d&rsquo;activer la redirection IP.
La redirection IP est le processus qui dirige les paquets IP qui voyagent
entre les interfaces réseaux du routeur.
Par défaut, OpenBSD ne fera pas de redirection des paquets IP entre les
différentes interfaces réseaux.
En d&rsquo;autres mots, les fonctions de routage (appelées aussi fonctions de
passerelles) sont désactivées.</p>
<p>Nous pouvons activer la redirection d&rsquo;IP en utilisant les commandes suivantes :</p>
<pre tabindex="0"><code># sysctl net.inet.ip.forwarding=1
# echo &#39;net.inet.ip.forwarding=1&#39; &gt;&gt; /etc/sysctl.conf
</code></pre><p>Maintenant OpenBSD sera capable de rediriger les paquets IPv4 depuis une
interface réseau vers une autre.
Ou, tel dans notre cas avec les 4 ports, d&rsquo;un port à l&rsquo;autre.
Regardez la page du manuel si vous avez besoin d&rsquo;IPv6.</p>
<h2 id="dhcp">DHCP</h2>
<p>Maintenant nous sommes prêts à paramétrer le service <a href="https://fr.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol" rel="external">DHCP</a>
que nous exécuterons pour nos différents PC et dispositifs attachés aux
différents LAN.
Avant, assurons-nous de lire et de comprendre les différentes options de
la page du manuel <a href="https://man.openbsd.org/dhcpd.conf" rel="external">dhcp.conf</a>.
Prenons aussi le temps de regarder la page de manuel <a href="https://man.openbsd.org/dhcp-options" rel="external">dhcp-options</a>
à propos des options que prend en charge dhcpd.</p>
<p>Nous avons une option pour cacher des adresses IP à de PC ou dispositifs
spécifiques qui se connectent sur nos différents ports.
Cela est nécessaire si nous voulons rediriger le trafic qui vient d&rsquo;Internet
vers quelque chose comme un serveur web.
Nous pouvons cacher une adresse IP spécifique vers un PC spécifique via
l&rsquo;adresse <a href="https://en.wikipedia.org/wiki/MAC_address" rel="external">MAC</a> de l&rsquo;interface
réseau de la machine concernée.</p>
<p>Dans ce cas, je réserverais toutes les adresses IP dans un ensemble allant
de 10 à 254 pour le DHCP, tandis que je laisserais les autres qui restent
pour les éventuelles adresses fixes dont je pourrais avoir besoin.</p>
<p>Éditer le fichier <code>/etc/dhcpd.conf</code> avec votre éditeur de texte favori et
adapter le à vos besoins.</p>
<pre tabindex="0"><code>subnet 192.168.1.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.1.1;
    option routers 192.168.1.1;
    range 192.168.1.10 192.168.1.254;
}
subnet 192.168.2.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.2.1;
    option routers 192.168.2.1;
    range 192.168.2.10 192.168.2.254;
}
subnet 192.168.3.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.3.1;
    option routers 192.168.3.1;
    range 192.168.3.10 192.168.3.254;
    host web.example.com {
        fixed-address 191.168.3.2;
        hardware ethernet 61:20:42:39:61:AF;
        option host-name &#34;webserver&#34;;
    }
}
</code></pre><p>La ligne <code>option domain-name-servers</code> spécifie le serveur DNS que nous allons
faire fonctionner sur notre routeur.</p>
<p>De plus l&rsquo;ordinateur qui est notre serveur web sur le LAN publique
a une adresse IP fixe et un nom d&rsquo;hôte fixé.</p>
<p>De même, si vous ne voulez pas segmenter le réseau en différentes parties,
mais que vous avez seulement besoin d&rsquo;un LAN alors vous pouvez juste laisser
de côté les autres sous-réseaux pour avoir juste cela :</p>
<pre tabindex="0"><code>subnet 192.168.1.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.1.1;
    option routers 192.168.1.1;
    range 192.168.1.10 192.168.1.254;
}
</code></pre><p>Ensuite, nous avons simplement besoin de nous assurer d&rsquo;activer et de démarrer
le service <code>dhcpd</code> :</p>
<pre tabindex="0"><code># rcctl enable dhcpd
# rcctl start dhcpd
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Regardez le chapitre
<a href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#ajouter-l&#39;option-domain-name-à-dhcp-et-utiliser-un-fqdn">Ajouter l&rsquo;option domain-name à DHCP et utiliser un FQDN</a> dans
l&rsquo;appendice pour savoir comment ajouter facilement un
<a href="https://fr.wikipedia.org/wiki/Fully_qualified_domain_name" rel="external">nom de domaine pleinement qualifié (FQDN)</a>
à votre paramétrage et comment vous pouvez utiliser l&rsquo;option <code>domain-name</code>
dans DHCP afin d&rsquo;éviter à avoir à écrire le FQDN à chaque fois que vous
en avez besoin.
Ce chapitre vous montrera aussi comment vous pouvez éviter d&rsquo;avoir à vous
souvenir des adresses IP si votre LAN a de multiples ordinateurs ou
dispositifs connectés.</div>

<h2 id="pf---un-pare-feu-filtrant">PF - un pare-feu filtrant</h2>
<p>Un pare-feu filtrant examine chaque paquet qui croise le pare-feu et décide
quel paquet accepter ou refuser, selon l&rsquo;examen des champs dans l&rsquo;IP et
les entêtes de protocole du paquet, et selon l&rsquo;ensemble des règles que
vous spécifiez.</p>
<p>Le filtrage de paquets fonctionne par inspection des adresses IP et du
port source et de destination contenus dans chaque paquet du protocole
TCP/IP (Transmission Control Protocol / Internet Protocol).
Les ports TCP/IP sont des numéros assignés à des services spécifiques
qui identifie pour quel service chaque paquet est destiné.</p>
<p>Une faiblesse commune des pare-feux simples à filtrage de paquets est que
le pare-feu examine chaque paquet de manière isolée sans tenir compte des
paquets qui ont déjà traversé le pare-feu et de ceux qui pourraient le
suivre.
Ils sont appelés pare-feu &ldquo;sans état&rdquo;.
Exploiter un filtrage de paquets sans état est assez facile.
PF d&rsquo;OpenBSD <strong>n&rsquo;est pas</strong> un pare-feu sans états, c&rsquo;est un
<a href="https://fr.wikipedia.org/wiki/Pare-feu_%C3%A0_%C3%A9tats" rel="external">pare-feu à états</a>.</p>
<p>Un pare-feu à états garde trace des connexions ouvertes et permet seulement
le trafic correspondant à une connexion existante ou ouvre une nouvelle
connexion permise.
Quand l&rsquo;état est spécifié par une règle correspondante, le pare-feu génère
dynamiquement des règles internes pour que chaque paquet anticipé puisse
être échangé durant la session.
Il a suffisamment de capacité de correspondance pour déterminer si un paquet
est valide pour une session.
Tout paquet qui ne correspond pas au modèle de session sera automatiquement
rejeté.</p>
<p>Un des avantages du filtrage à états est que c&rsquo;est très rapide.
Il vous permet de vous focaliser sur le fait de bloquer ou laisser passer
de nouvelles sessions.
Si une nouvelle session est passée, tous les paquets conséquents sont
automatiquement alloués et tout paquet imposteur sera automatiquement
rejeté.
Si une nouvelle session est bloquée, aucun des paquets conséquents n&rsquo;est
autorisé.
Le filtrage à états fournit aussi des capacités avancées de correspondance
capables de se défendre contre le flood de différentes méthodes d&rsquo;attaques
employées par des attaquants.</p>
<p>La Traduction d&rsquo;Adresse Réseau (NAT) permet à un réseau privé derrière le
pare-feu de partager une adresse IP publique unique.
La NAT permet à chaque ordinateur du réseau privé d&rsquo;avoir un accès à Internet,
sans avoir besoin de comptes multiples à Internet, ou de multiples adresses
IP publiques.
La NAT traduira automatiquement l&rsquo;adresse IP du réseau privé pour les
ordinateurs et dispositifs sur le réseau vers l&rsquo;unique adresse IP publique
lorsque les paquets sortent du pare-feu vers Internet.
La NAT assume aussi la traduction inverse pour les paquets de retour.
Avec la NAT, vous pouvez rediriger un trafic spécifique, couramment déterminé
par un numéro de port ou un ensemble de numéros de port, entrant depuis
votre adresse IP publique depuis Internet vers le ou les serveurs spécifiques
localisés quelque part dans votre réseau local.</p>
<p><a href="https://man.openbsd.org/pf" rel="external">PF - Packet Filter</a> est le système de pare-feu
d&rsquo;OpenBSD pour le filtrage du trafic TCP/IP et faisant de la NAT.
PF est aussi capable de normaliser ou conditionner le trafic TCP/IP, aussi
bien que gérer le contrôle de la bande passante ou la priorisation de paquets.</p>
<p>PF est activement maintenu et développé par l&rsquo;entière équipe d&rsquo;OpenBSD.</p>
<h3 id="paramétrage-de-pf">Paramétrage de PF</h3>
<p>Avant que nous commencions, je présume que vous avez lu à la fois et le
<a href="https://www.openbsd.org/faq/pf/index.html" rel="external">Guide de l&rsquo;Utilisateur de PF</a>
et la page du manuel <a href="https://man.openbsd.org/pf.conf" rel="external">pf.conf</a>, spécifiquement
la page du manuel qui est très importante.
Même si vous ne comprenez pas toutes les différentes options, assurez-vous
de lire la documentation !
Lisez la page du manuel <a href="https://man.openbsd.org/pf" rel="external">pf</a> pour avoir une
complète compréhension en profondeur de ce que PF peut faire.</p>
<p>De plus, laissez-moi commencer par vous dire que même si la syntaxe de PF
est très lisible, il est <strong>très facile</strong> de faire des erreurs lors de l&rsquo;écriture
des règles de pare-feu.
Même des seniors et des administrateurs systèmes expérimentés font des
erreurs lors de l&rsquo;écriture des règles de pare-feu.</p>
<p>Écrire des règles de pare-feu requiert que vous ayez planifié vos buts
avec attention, compris comment implémenter les différentes règles avant
d&rsquo;obtenir le résultat attendu, et en même temps de prendre vos précautions
afin de vous éviter de vous tromper et de vous déconnecter accidentellement :)
Je pense que nous l&rsquo;avons tous fait à un moment ou l&rsquo;autre, que ce soit
dans la précipitation, la fatigue ou simplement par erreur.
J&rsquo;ai vécu cela de nombreuses fois.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Veuillez noter que j&rsquo;ai fait de mon mieux pour garder les choses simples
autant que possible et que j&rsquo;utilise autant de commentaires afin d&rsquo;expliquer
ce que fait chaque règle. En même temps, j&rsquo;ai testé chaque règle et surveillé
l&rsquo;impact et fait de mon mieux pour éviter les complications et erreurs.</div>

<p>La partie la plus importante est de ne pas faire de suppositions.
Testez toujours vos règles de manière approfondie.
Si quelque chose ne fonctionne pas, essayez de supprimer autant de règles
que possible pour ne garder que le strict minimum. Puis introduisez une
règle à la fois jusqu&rsquo;à trouver la règle qui pose problème.
Enfin, continuez avec le paramétrage étape par étape.</p>
<p>La partie réellement difficile est de se souvenir de comment les paquets
arrivent sur une interface, comment ils sont rediriger vers une machine
sur une autre interface, et de relier correctement ce &ldquo;voyage&rdquo; aux termes
<strong>pass in</strong>, <strong>pass out</strong>, <strong>block in</strong>, <strong>block out</strong>, <strong>from</strong> et <strong>to</strong>.
Souvent, ces termes ne fonctionnent pas exactement comme nous avons tendance
à le penser.</p>
<h3 id="éclaircissements">Éclaircissements</h3>
<p>Je tiens à démarrer en clarifiant certains des paramètres communs par défaut
et des mots clés dans PF.</p>
<p>Quand nous parlons du traffic <strong>pass in</strong> ou <strong>pass out</strong>, une bonne manière
de se rappeler ce dont il s&rsquo;agit est de penser en terme de paquets de données.
Nous utilisons <strong>pass in</strong> pour les paquets de données entrants qui viennent
d&rsquo;ordinateurs vers une interface réseau (les ordinateurs étant rattachés
à ce périphérique réseau) et <strong>pass out</strong> pour les paquets de données venant
de l&rsquo;interface réseau vers les ordinateurs.</p>
<p>Le format est soit que nous filtrons les paquets de données sur la destination :</p>
<pre tabindex="0"><code>from source IP to destination IP [on]  port
</code></pre><p>Soit que nous filtrons les paquets de données sur la source :</p>
<pre tabindex="0"><code>from source IP [on] port to destination
</code></pre><p>Veuillez noter que la partie <code>[on]</code> n&rsquo;est pas une partie de la syntaxe.</p>
<ul>
<li>
<p><code>quick</code></p>
<ul>
<li>Si un paquet correspond à une règle <code>pass</code>, <code>block</code> ou <code>match</code> avec
le critère <code>quick</code>, le paquet <strong>est passé sans inspection des règles de
filtrage conséquentes</strong>.
La règle avec le critère <code>quick</code> devient la dernière règle correspondante.</li>
</ul>
</li>
<li>
<p><code>keep state</code></p>
<ul>
<li>Vous n&rsquo;avez pas besoin de spécifier le critère <code>keep state</code> pour des
règles spécifiques <code>pass</code> ou <code>block</code>.
La première fois où un paquet correspond à une règle <code>pass</code> ou <code>block</code>,
<strong>un état d&rsquo;entrée est créé par défaut</strong>. <br>
Seulement si aucune règle ne correspond au paquet, l&rsquo;action par défaut
est <strong>de passer le paquet sans créer d&rsquo;état</strong>.</li>
</ul>
</li>
<li>
<p><code>on</code> interface/<code>any</code></p>
<ul>
<li>Cette règle s&rsquo;applique seulement aux paquets <strong>qui sont entrants</strong>,
ou <strong>qui passent au-travers</strong> de cette interface en particulier ou d&rsquo;un
groupe d&rsquo;interface. <br>
Le critère <code>on any</code> correspondra à toute interface existante, exceptée
celles de bouclage loopback.</li>
</ul>
</li>
<li>
<p><code>inet</code>/<code>inet6</code></p>
<ul>
<li>Les critères <code>inet</code> et <code>inet6</code> signifie que cette règle s&rsquo;applique
seulement aux paquets <strong>entrants</strong>, ou <strong>passant au-travers</strong> ce domaine
particulier de routage, soit IPv4, soit IPv6. <br>
Vous pouvez appliquer des règles pour des domaines particuliers de routage
sans spécifier l&rsquo;interface réseau. Dans de ce cas, la règle correspondra
à tout trafic de toute nature sur toutes les interfaces réseaux. En
spécifiant <code>inet</code>, vous adressez explicitement le trafic IPv4 seulement.</li>
</ul>
</li>
<li>
<p><code>proto</code></p>
<ul>
<li>Se limiter à un protocole est faisable en utilisant le critère <code>proto</code>.
Une règle s&rsquo;applique <strong>seulement aux paquets de ce protocole</strong>, les autres
protocoles ne sont pas affectés. Vous pouvez chercher les protocoles
dans le fichier <code>/etc/protocols</code>. Les protocoles communs sont <a href="https://fr.wikipedia.org/wiki/Internet_Control_Message_Protocol" rel="external">ICMP</a>
<a href="https://fr.wikipedia.org/wiki/Transmission_Control_Protocol" rel="external">TCP</a> et
<a href="https://fr.wikipedia.org/wiki/User_Datagram_Protocol" rel="external">UDP</a>.</li>
</ul>
</li>
<li>
<p><code>in</code> et <code>out</code></p>
<ul>
<li>C&rsquo;est l&rsquo;une des parties les plus faciles où se tromper : la direction
du trafic. Un paquet <strong>entre</strong> ou <strong>sort</strong> toujours par le port sur
l&rsquo;interface Ethernet. <code>in</code> et <code>out</code> s&rsquo;applique aux paquets entrants
et sortants au-travers du port Ethernet physique auquel est attaché
le câble Ethernet. <strong>Si rien n&rsquo;est spécifié, la règle correspondra
aux paquets dans les deux directions</strong>. <br>
<code>in</code> et <code>out</code> ne sont <strong>jamais</strong> utilisé pour gérer le trafic venant
d&rsquo; une interface réseau vers une autre, ce qui est fait par la NAT, en
utilisant les options <code>nat-to</code> et <code>rdr-to</code>. <code>in</code> et <code>out</code> gèrent
seulement le trafic <strong>entrant</strong> et <strong>sortant</strong> du port Ethernet physique
d&rsquo;une même carte.</li>
</ul>
</li>
<li>
<p><code>from</code> et <code>to</code></p>
<ul>
<li>Les critères <code>from</code> et <code>to</code> s&rsquo;appliquent <strong>seulement aux paquets avec
une adresse et des ports source et destination spécifiés</strong>.
Des deux, du nom d&rsquo;hôte ou de l&rsquo;adresse IP, ou du port, voire les
spécifications OS sont optionnels. <br>
Quand nous avons affaire avec un routeur ayant de multiples interfaces
réseaux, il est facile de penser cela :
<em>Je veux passer les paquets entrants depuis l&rsquo;interface externe
(l&rsquo;interface réseau attachée à Internet) puis qu&rsquo;ils aillent sur la
première interface LAN et de là vers un PC spécifique sur le LAN</em>
signifiant que nous suivront le &ldquo;chemin des données&rdquo; dans notre esprit,
et alors nous écrivons quelque chose comme cela :
<code>pass in on $ext_if from $ext_if to $dmz port 80</code>.
Mais cela ne fait pas apparaître &ldquo;par magie&rdquo; le trafic HTTP sur le port 80
au PC ayant l&rsquo;adresse IP spécifique sur le LAN. Il nous faudrait aussi une
règle <code>pass out</code> spécifique et déterminer exactement sur quelle machine
nous voulons que les données arrivent.
À moins que vous n&rsquo;ayez affaire à une exigence très spécifique, vous
n&rsquo;aurez jamais besoin d&rsquo;une telle règle dans votre jeu de règles !
Les fonctionnalités <a href="https://www.openbsd.org/faq/pf/filter.html#urpf" rel="external">uRPF (Unicast Reverse Path Forwardint)</a>
de PF protégeront votre réseau interne aussi bien avec un paramétrage
de base de NAT, avec l&rsquo;option <code>nat-to</code> et une redirection avec l&rsquo;option
<code>rdr-to</code>, PF gérera les paquets venant de l&rsquo;intérieur vers l&rsquo;extérieur
et vice-versa. <br>
Le paramètre <code>all</code> est équivalent à l&rsquo;écriture <code>from any to any</code>.
<strong>Sans une direction explicitement déclarée, la règle par défaut est
<code>from any to any</code></strong>. Cette règle : <code>pass in on $p_lan proto udp to port dns</code>
se traduit par : <code>pass in on em3 inet proto udp from any to any port = 53</code>. <br>
Il n&rsquo;est pas non plus nécessaire d&rsquo;utiliser <code>to any port dns</code>, la
partie <code>any</code> étant celle par défaut. Vous avez cependant besoin de
<code>to port dns</code>.</li>
</ul>
</li>
<li>
<p><code>nat-to</code> et <code>rdr-to</code></p>
<ul>
<li>Les options NAT <strong>modifient soit l&rsquo;adresse et le port source ou destination
des paquets associées à une connexion d&rsquo;états</strong>.
PF modifie l&rsquo;adresse spécifié et/ou le port dans le paquet et recalcule
les sommes de contrôle IP, TCP et UDP nécessaires. <br>
Une option <code>nat-to</code> spécifie <strong>que les adresses IP ont été changées car
le paquet traverse l&rsquo;interface donnée</strong>.
Cette technique permet à une ou plusieurs adresses IP sur l&rsquo;hôte traduisant
(le routeur OpenBSD) de prendre en charge le trafic réseau pour un ensemble
plus grand de machines sur le réseau <strong>interne</strong>, tel qu&rsquo;un LAN. <br>
L&rsquo;option <code>nat-to</code> est habituellement appliqué à la sortie, signifiant
<strong>redirigé depuis le réseau interne vers Internet</strong>.
<code>nat-to</code> vers une adresse IP locale <strong>n&rsquo;est pas pris en charge</strong>. <br>
L&rsquo;option <code>rdr-to</code> est appliquée généralement à l&rsquo;entrée, signifiant
<strong>redirigé depuis Internet vers le réseau interne</strong>.</li>
</ul>
</li>
<li>
<p>Liste d&rsquo;éléments et d&rsquo;ensemble d&rsquo;adresses et de ports</p>
<ul>
<li>Quand vous avez besoin de spécifier de multiples éléments, e.g. de
multiples numéros de ports, vous pouvez les séparer avec une espace
ou une virgule.
Tel que <code>port { 53 853 }</code> ou <code>port { 53, 853 }</code>. <br>
Un ensemble d&rsquo;adresses est spécifié en utilisant l&rsquo;opérateur <code>-</code>.
e.g. <code>192.168.1.2 - 192.168.1.10</code> signifie toutes les adresses IP
de 192.168.1.2 à 192.168.1.10, incluant les deux. <br>
Un ensemble de ports a de multiples paramètres ; regardez la page du
manuel <a href="https://man.openbsd.org/pf.conf" rel="external">pf.conf</a> et cherchez le texte
<em>&ldquo;Ports and ranges of ports are specified using these operators&rdquo;</em>.</li>
</ul>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Veuillez noter que chaque fois qu&rsquo;un paquet traité par PF arrive ou part
d&rsquo;une interface, les règles de filtrage sont évaluées dans un ordre séquentiel,
de la première à la dernière.
Concernant <code>block</code> et <code>pass</code>, <strong>la dernière règle correspondante décide
de quelle action prise</strong>.
Si aucune règle ne correspond au paquet, l&rsquo;action par défaut est de laisser
passer le paquet sans créer d&rsquo;état.
Pour <code>match</code>, les règles sont évaluées <strong>chaque fois qu&rsquo;elles correspondent</strong>.</div>

<h3 id="résolution-de-nom-de-domaine-ou-dhôte">Résolution de nom de domaine ou d&rsquo;hôte</h3>
<p>Si vous décidez d&rsquo;utiliser des noms d&rsquo;hôtes et/ou des noms de domaines
dans votre paramétrage de PF, vous avez besoin de savoir que <strong>la résolution
de tout nom de domaine ou d&rsquo;hôte est faite au moment du chargement du jeu
de règles</strong>.
Cela signifie que quand l&rsquo;adresse IP d&rsquo;un hôte ou d&rsquo;un nom de domaine change,
le jeu de règles <strong>doit être rechargé pour que le changement soit pris en
compte par le noyau</strong>.
Il n&rsquo;est pas possible qu&rsquo;à chaque fois qu&rsquo;une règle s&rsquo;applique, pour un
nom d&rsquo;hôte ou de domaine listé, que PF fasse une nouvelle requête DNS pour
ce nom d&rsquo;hôte ou de domaine particulier.
La requête DNS s&rsquo;effectue seulement lors du chargement du jeu de règles.</p>
<p>Cela signifie aussi que vous devez vous assurer que le serveur DNS que vous
utiliser soit actif et fonctionnel <strong>avant</strong> que PF ne démarre, autrement
PF échouera à charger le jeu de règles car il ne peut résoudre le nom d'
hôte ou de domaine.</p>
<p>Sur OpenBSD, PF démarre <strong>avant</strong> Unbound ou tout autre service DNS installé,
ce qui est la bonne manière de faire d&rsquo;un point de vue de la sécurité.</p>
<p>Je vous conseille d&rsquo;éviter l&rsquo;utilisation de noms d&rsquo;hôtes ou de noms de
domaines lorsque vous utilisez les règles PF et de privilégier les adresses
IP, si possible.
Il est possible d&rsquo;utiliser les noms d&rsquo;hôtes et noms de domaines, mais
l&rsquo;adressage d&rsquo;IP directement est de loin le plus facile et le plus sûr.</p>
<h3 id="un-jeu-de-règles">Un jeu de règles</h3>
<p>C&rsquo;est une bonne idée de tester votre jeu de règles sur une machine de test.
Il y a presque toujours plus d&rsquo;une manière de faire pour arriver au même
résultat. Selon mon humble avis, la meilleure manière est celle qui vous
permet d&rsquo;être le plus clair (i.e. facile à comprendre).</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne jamais écrire de nouveaux jeux de règles sur un dispositif à
distance où vous êtes actif à moins de savoir ce que vous faites.
Être déconnecté d&rsquo;une machine à distance n&rsquo;est jamais agréable.</div>

<p>Essayez de trouver comment vous pouvez faire en sorte que vos règles soient
aussi claires et simples que possible, en utilisant les valeurs par
défaut, quand c&rsquo;est possible.
N&rsquo;ayez pas peur de spécifier des critères qui rendent les règles plus
claires à comprendre, quand bien même ils sont identiques aux valeurs par
défaut.
Une valeur par défaut peut être <code>any to any</code>, et vous pouvez laisser cela
de côté, mais il serait plus facile de comprendre une règle particulière
quand il est écrit <code>any to any</code> textuellement dans le fichier de configuration.</p>
<p>Vous pouvez toujours analyser le jeu de règles et vérifier les erreurs
sans qu&rsquo;il soit déployé avec la commande <code>pfctl -nf /etc/pf.conf</code>.
Une fois que vous avez chargé le jeu de règles avec la commande <code>pfctl -f /etc/pf.conf</code>,
vous pouvez voir comment le jeu de règles a été traduit par PF avec la
commande <code>pfctl -s rules</code>, que je vous conseille d&rsquo;utiliser régulièrement.</p>
<p>Je préfère organiser mon jeu de règles par section et commentaires, je
ferais ainsi dans cet exemple.</p>
<p>Utilisez votre éditeur de texte favori et ouvrez le fichier <code>/etc/pf.conf</code>.</p>
<p>En premier, nous paramétrons quelques macros pour mieux se souvenir quelles
interfaces réseaux nous utilisons.
Utiliser des macros pour les interfaces réseaux rend aussi plus facile le
changement du nom du pilote de la carte si vous achetez une nouvelle carte,
ou de multiples nouvelles cartes.</p>
<pre tabindex="0"><code>#---------------------------------#
# Macros
#---------------------------------#

ext_if=&#34;em0&#34; # Interface externe connectée au modem du FAI (Internet).
g_lan=&#34;em1&#34;  # LAN PC Adultes
c_lan=&#34;em2&#34;  # LAN PC Enfants
p_lan=&#34;em3&#34;  # LAN Publique.
</code></pre><p>Ensuite, nous paramétrons une table pour les adresses IP non routable.
Nous faisons cela, car une mauvaise configuration réseau courante est
celle qui permet du trafic avec des adresses non routable vers Internet.
Nous utiliserons la table dans notre jeu de règles afin de bloquer
tout essai d&rsquo;initier un contact avec les adresses non routable au-travers
de l&rsquo;interface externe du routeur.</p>
<pre tabindex="0"><code>#---------------------------------#
# Tables
#---------------------------------#

# Ceci est une table d&#39;adresses IP privées non routables.
table &lt;martians&gt; { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16     \
                   172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
                   192.168.0.0/16 198.18.0.0/15 198.51.100.0/24        \
                   203.0.113.0/24 }
</code></pre>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Veuillez noter que les macros et les tables sont toujours écrites en début
du fichier <code>/etc/pf.conf</code>.</div>

<p>Alors, commençons avec une <strong>politique de blocage par défaut</strong> et
activons une série de fonctionnalités de protection.</p>
<pre tabindex="0"><code>#---------------------------------#
# Protect and block by default
#---------------------------------#
set skip on lo0

# Protection vs l&#39;usurpation d&#39;adresses sur toutes les interfaces réseaux.
block in from no-route
block in quick from urpf-failed

# Bloquage des adresses privées non routable.
# Utilisation du paramétre &#34;quick&#34; pour que cette règle soit la dernière traversée.
block in quick on $ext_if from &lt;martians&gt; to any
block return out quick on $ext_if from any to &lt;martians&gt;

# Bloquage par défaut de tout trafic sur toutes les interfaces réseaux.
block return in on { $g_lan $c_lan $dmz }

# Bloquage par défaut de tout trafic sur l&#39;interface reliée à Internet
# avec journalisation
block drop in log on $ext_if

# Autoriser ICMP.
match in on $ext_if inet proto icmp icmp-type {echoreq } tag ICMP_IN
block drop in on $ext_if proto icmp
pass in proto icmp tagged ICMP_IN max-pkt-rate 100/10

# Autoriser le routeur à accéder à Internet, au-travers de son interface réseau dédiée
pass out inet from $ext_if
</code></pre><p>Les adresses IP contenues dans la macro <code>martians</code> constituent les adresses
référencées dans la <a href="https://tools.ietf.org/html/rfc1918" rel="external">RFC1918</a> qui ne
doivent pas être utilisées sur Internet.
Le trafic venant ou allant vers de telles adresses doit être abandonné
sur l&rsquo;interface externe du routeur.</p>
<p>Dans les précédentes versions de ce guide (avant la version 1.5.0), j&rsquo;avais
l&rsquo;habitude d&rsquo;utiliser l&rsquo;instruction <a href="https://man.openbsd.org/pf.conf#Scrub" rel="external">scrub</a>
dans le paramétrage ci-dessus, toutefois après avoir consulté l&rsquo;équipe
OpenBSD avec <a href="http://henningbrauer.com/" rel="external">Henning Brauer</a> (Merci à Henning !)
et fais de plus amples recherches, j&rsquo;ai décidé de la supprimer car elle
ne traite que des cas très spécifiques (veuillez lire la documentation).
Vous aurez besoin de la règle <code>scrub</code> seulement si un hôte sur votre réseau
génére des paquets fragmentés avec le drapeau &ldquo;dont-fragment&rdquo;.
Le comportement par défaut de PF sans la règle <code>scrub</code> est mieux adapté
à un usage général.</p>
<p>La <a href="https://www.openbsd.org/faq/pf/example1.html" rel="external">FAQ</a> d&rsquo;OpenBSD contient
un exemple de paramétrage pour un routeur très basique, avec certaines
valeurs spécifiques pour <code>scrub</code>, mais ma recommandation est d&rsquo;utiliser
seulement <code>scrub</code> là où vous savez en avoir besoin.
Si vous n&rsquo;en avez pas besoin, insérez-la dans la configuration après la
règle <code>set skip</code> pour l&rsquo;interface de bouclage locale, tel que :</p>
<pre tabindex="0"><code>set skip on lo0
match in all scrub
</code></pre><p>Et ensuite ajoutez les paramètres à la règle <code>scrub</code> dont vous avez besoin.</p>
<p>J&rsquo;utilisais aussi la règle <a href="https://man.openbsd.org/pf.conf#Blocking_Spoofed_Traffic" rel="external">antispoof</a>
suivante dans la section de protection contre l&rsquo;usurpation :</p>
<pre tabindex="0"><code>antispoof quick for { $g_lan $c_lan $dmz }
</code></pre><p>J&rsquo;ai depuis supprimé la règle <code>antispoof</code> puisque la fonctionnalité
<a href="https://www.openbsd.org/faq/pf/filter.html#urpf" rel="external">uRPF (Unicast Reverse Path Forwarding)</a>
que PF fournit a la même fonctionnalité, et en tant que tel nous n&rsquo;en avons
plus besoin, à la place nous utilisons juste la règle <code>block in quick from urpf-failed</code>.</p>
<p>L&rsquo;information suivante à-propos du critère <code>antispoof</code> est gardée à des
fins d&rsquo;éducation.</p>
<p>L&rsquo;usurpation est lorsque quelqu&rsquo;un fabrique une adresse IP. Le critère
<code>antispoof</code> s&rsquo;étend à un ensemble de règles de filtrage qui empêcheront
tout trafic avec une adresse IP source du réseau (directement connecté
à l&rsquo;interface spécifiée) entrant sur le système par une autre interface.
Cela est parfois appelé &ldquo;bleeding over&rdquo; ou &ldquo;bleeding through&rdquo;.</p>
<p>La directive <code>antispoof</code> est traduite par PF par ce qui suit :</p>
<pre tabindex="0"><code>block drop in quick on ! em1 inet from 192.168.1.0/24 to any
block drop in quick inet from 192.168.1.1 to any
block drop in quick on ! em2 inet from 192.168.2.0/24 to any
block drop in quick inet from 192.168.2.1 to any
block drop in quick on ! em3 inet from 192.168.3.0/24 to any
block drop in quick inet from 192.168.3.1 to any
</code></pre><p>Si nous prenons, e.g., la règle <code>block drop in quick on ! em1 inet from 192.168.1.0/24 to any</code>
de l&rsquo;interface réseau <code>em1</code> qui signifie alors : <em>bloque tout trafic venant
du réseau ayant une adresse IP comprise entre 192.168.1.1 et 192.168.1.255,
qui n&rsquo;est pas originaire depuis l&rsquo;interface em1 elle-même, et qui va ailleurs</em>.
Puisque l&rsquo;interface <code>em1</code> est l&rsquo;interface réseau en charge de toutes les
adresses IP dans cet ensemble spécifique, alors aucun trafic avec de telles
adresses IP ne pourra être originaire de toute autre interface réseau.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">L&rsquo;utilisation d&rsquo;<code>antispoof</code> doit être <strong>restreinte</strong> aux interfaces qui
ont une adresse IP assignée, ce qui signifie que si vous avez des interfaces
réseaux inutilisées, ou des ports d&rsquo;une interface réseau, assurez-vous
d&rsquo;assigner une adresse IP à chacune ou de ne pas les inclure dans l&rsquo;option
<code>antispoof</code>.</div>

<p>Ainsi que je l&rsquo;ai mentionnée, j&rsquo;ai supprimé la règle <code>antispoof</code> et nous
utiliserons à la place la vérification stricte d&rsquo;uRPF.
Lorsqu&rsquo;un paquet passe dans la vérification d&rsquo;uRPF, l&rsquo;adresse IP source
du paquet est recherchée dans la table de routage.
Si l&rsquo;interface de sortie est trouvée dans la table de routage et que l&rsquo;entrée
est la même que l&rsquo;interface du paquet qui vient juste d&rsquo;entrer, alors la
vérification d&rsquo;uRPF autorise.
Autrement, il est possible que le paquet ait son adresse IP source usurpée
ainsi il sera bloqué.</p>
<p>Nous allons permettre <a href="https://fr.wikipedia.org/wiki/Internet_Control_Message_Protocol" rel="external">ICMP</a>
dans notre paramétrage, quand bien même des administrateurs réseaux bloquent
complètement ICMP.
La plupart des personnes bloquent complètement ICMP à cause d&rsquo;actions
injustifiées telles que les attaques par découverte de réseaux, les canaux
de communication, le <a href="https://en.wikipedia.org/wiki/Ping_sweep" rel="external">ping sweep</a>,
le <a href="https://fr.wikipedia.org/wiki/Ping_flood" rel="external">ping flood</a>, le <a href="https://en.wikipedia.org/wiki/ICMP_tunnel" rel="external">tunnel d&rsquo;ICMP</a>,
et la <a href="https://fr.wikipedia.org/wiki/Internet_Control_Message_Protocol#Signification_du_type_5_(redirection)" rel="external">redirection d&rsquo;ICMP</a>.
Toutefois, ICMP est bien plus que répondre à des ping.
Si nous bloquons complètement ICMP, les diagnostics, la fiabilité, et la
performance réseau peuvent être défectueuses puisque des mécanismes importants
sont désactivés lorsque le protocole ICMP est restreint.</p>
<p>Voici certaines raisons pour lesquelles ICMP ne devrait pas être bloqué :</p>
<ul>
<li>La découverte Path MTU (PMTUD) est utilisée pour déterminer la taille
maximale de l&rsquo;unité de transmission pour les dispositifs réseau qui relient
la source et la destination afin d&rsquo;éviter la fragmentation IP.
TCP dépend des paquets ICMP de type 3 code 4 pour &ldquo;Path MTU Discovery&rdquo;.
ICMP type 3 code 4 et la taille maximale des paquets sont retournés quand
un paquet excède la taille MTU d&rsquo;un dispositif réseau connecté.
Quand les messages ICMP sont bloqués, le système de destination requête
continuellement des paquets non délivrés et le système source continue à
les renvoyer indéfiniment mais en vain.
Ce comportement peut avoir pour résultat un <a href="https://fr.wikipedia.org/wiki/Black_hole_(informatique)" rel="external">trou noir</a>
ICMP (des connexions IP congestionnées et des transmissions cassées).</li>
<li>Time to live (TTL) définit le temps de vie d&rsquo;un paquet de données.
Un réseau où ICMP est bloqué ne recevra pas le message de type 11, temps
écoulé, code 0, temps écoulé dans le transit des messages d&rsquo;erreur.
Cela signifie que l&rsquo;hôte source ne sera pas notifié pour augmenter le temps
de vie des données afin d&rsquo;atteindre l&rsquo;hôte de destination, si le datagram
échoue à atteindre l&rsquo;hôte de destination.</li>
<li>Une mauvaise performance du fait de bloquer la redirection ICMP.
La redirection ICMP est utilisée par un routeur pour informer un hôte d&rsquo;un
chemin direct entre l&rsquo;hôte source et celui de destination.
Cela réduit le nombre de saut que les données ont à faire pour atteindre
la destination.
Avec ICMP bloqué, l&rsquo;hôte ne fera jamais attention à la route la plus optimale
vers la destination.</li>
</ul>
<p>Dans le paramétrage ci-dessus, nous permettons ICMP, mais nous mettons une
&ldquo;limite de taux&rdquo; du nombre de requêtes ping auxquelles le routeur répondra.
Avec le critère <code>max-pkt-rate 100/10</code>, le routeur arrêtera de répondre aux
ping si nous en avons plus de 100 en 10 secondes.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si vous souhaitez toujours bloquer complètement ICMP pour une raison quelconque,
il suffit de supprimer les 3 règles après le commentaire &ldquo;Allow ICMP&rdquo;.</div>

<p>Maintenant paramétrons le segment LAN pour les adultes de la maison.</p>
<pre tabindex="0"><code>#---------------------------------#
# Paramétrage du réseau LAN adulte
#---------------------------------#

# Autoriser tout ordinateur ou dispositif sur le LAN adulte à envoyer des
# paquets de données entrants dans l&#39;interface réseau. Cela signifie que
# tout ordinateur attaché à cette interface réseau peut envoyer des données
# partout, i.e. sur Internet ou tout ordinateur attaché au routeur.
pass in on $g_lan

# Toujours bloquer les requêtes DNS non adressées à notre serveur DNS.
block return in quick on $g_lan proto { udp tcp } to ! $g_lan port { 53 853 }

# J&#39;ai une imprimante réseau et je ne veux pas qu&#39;elle &#34;téléphone maison&#34;.
# L&#39;imprimange réseau à l&#39;adresse IP  192.168.1.8.
block in quick on $g_lan from 192.168.1.8

# Autoriser les paquets de données venant du routeur à sortir par l&#39;interface
# réseau vers les ordinateurs et dispositifs attachés à l&#39;interface du
# réseau Adultes.
# Sans cela nous ne pouvons même pas pingués les ordinateurs attachés à
# l&#39;interface du réseau Adultes depuis le routeur lui-même.
pass out on $g_lan inet keep state
</code></pre><p>Dans cet exemple, j&rsquo;ai une imprimante réseau attachée au réseau des adultes
et je ne veux pas qu&rsquo;elle accéde à Internet ou ailleurs (juste en cas où
il y aurait une sorte de micrologiciel espion).
Nous le faisons en disant : <em>bloque toutes les données entrantes sur em1
venant de l&rsquo;adresse IP 192.168.1.8 allant vers toute adresse IP</em>.</p>
<p>De plus, nous nous assurons que toutes les requêtes DNS sur les ports 53
(DNS régulier) et 853 (DNS sur TLS) soient toujours bloquées si elles ne
viennent pas de notre serveur DNS.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Avant, j&rsquo;utilisais la redirection du trafic sur le port 53 non adressé à
notre serveur DNS vers notre serveur DNS.
Je faisais cela parce que nous bloquions toute requête DNS sur le port 53,
soit avec <code>return</code> ou <code>drop</code>, la requête prenant un délai sur le client,
ce qui avait pour conséquence que beaucoup de clients obtenaient un délai
sur la réponse.
Depuis j&rsquo;ai changé cela en block parce que je crois que c&rsquo;est une meilleure
approche.
Tous les clients DNS ont besoin de réaliser que la communication sur le
port 53 est bloqué, à moins qu&rsquo;elle ne soit adressée à notre serveur DNS.
C&rsquo;est aussi important quand nous avons des problèmes sur notre réseau.
Si nous avons une réponse redirigée vers notre serveur DNS, nous pourrions
ne pas être averti que nous avons été redirigé.</div>


<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">DNS utilise en premier UDP (User Datagram Protocol) sur le port 53 pour
servir les requêtes, mais quand la longueur de la réponse excède 512 bits
et que le client et le serveur prennent en charge EDNS, des paquets UDP
plus grands sont utilisés.
Toutefois, la requête est envoyée en utilisant TCP (Transmission Control Protocol).
Certaines implémentations de résolveurs DNS utilisent TCP pour toutes les
requêtes.
Ainsi nous avons besoin des deux protocoles UDP et TCP dans la règle pour
le port 53.</div>

<p>Le réseau LAN pour les enfants est très similaire.</p>
<pre tabindex="0"><code>#---------------------------------#
# Paramétrage LAN enfants
#---------------------------------#

# Autoriser tout PC du LAN Enfant à envoyer des données au-travers du port
# de l&#39;interface réseau
pass in on $c_lan

# Toujours bloquer les requêtes DNS qui ne sont pas adressées à notre
# serveur DNS.
block return in quick on $c_lan proto { udp tcp} to ! $c_lan port { 53 853 }

# Autorise les paquets de données à passer venant du routeur au-travers
# l&#39;interface réseau vers les ordinateurs ou dispositifs attachés au
# LAN Enfants.
# Sans cela, nous ne pourrions même pas pingués les ordinateurs depuis
# le routeur lui-même
pass out on $c_lan inet keep state
</code></pre><p>Actuellement les deux réseaux Adultes et Enfants ont le même accès à Internet.
Un paramétrage plus restrictif est mentionné dans le chapitre
&ldquo;<a href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#une-liste-blanche-pour-les-enfants">Liste Blanche pour enfants</a>&rdquo;.</p>
<p>Occupons nous alors de la DMZ, i.e. de l&rsquo;interface réseau qui répond publiquement
au serveur web.
Puisque nous avons un serveur web publique, nous allons définir un certain
nombre de restrictions.
Si le serveur web est compromis, l&rsquo;intrus aura du mal à trouver ce qui est
localisé dans notre réseau interne.</p>
<p>Nous bloquons tous les accès excepté le DHCP, afin que le serveur web
ait une adresse IP depuis notre routeur, et alors d&rsquo;ouvrir <strong>seulement
manuellement</strong> certaines choses pour quand nous avons besoin de mettre à
jour la machine ou quoi que ce soit d&rsquo;autres.
J&rsquo;ai commenté les options dont nous avons besoins, quand nous avons besoin
de telles choses, laissant les parties restreintes actives.
Quand vous aurez besoin de mettre à jour le serveur, ouvrez l&rsquo;accès DNS
et l&rsquo;accès général à Internet.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Plutôt que changer manuellement le jeu de règles à chaque fois où nous avons
besoin de mettre à jour le serveur web, nous pouvons aussi utiliser une
<a href="https://man.openbsd.org/pf.conf#ANCHORS" rel="external">ancre</a>, mais par esprit de
simplification, nous ne ferons pas cela ici.</div>

<pre tabindex="0"><code>#---------------------------------#
# Paramétrage DMZ
#---------------------------------#

# Autorise tout ordinateur ou dispositif attaché à l&#39;interface réseau DMZ
# à obtenir une adresse IP venant du DHCP depuis le routeur
pass in on $dmz inet proto udp from any port 67

# Autorise tout ordinateur ou dispositif attaché à l&#39;interface réseau DMZ
# à faire des requêtes DNS. (décommentez si besoin)
#pass in on $dmz inet proto udp from any port 53

# Toujours bloquer les requêtes DNS non adressées à notre serveur DNS.
block return in quick on $dmz proto { udp tcp} to ! $dmz port { 53 853 }

# Pour autoriser tout ordinateur attaché à l&#39;interface réseau DMZ à accéder
# à Internet, décommentez la ligne ci-dessous.
# (Cela est pertinent pour les màj)
#pass in on $dmz inet

# No matter what, we do not want the DMZ segment to reach any of the other
# network segments so we explicitly use a block last.
#
# We have several options. If we use this:
#
#   block drop in on $dmz to 192.168/16
#
# Then we block for all subnets, but this also means that the computers
# attached to the DMZ NIC cannot do DNS queries when they need to be upgraded.
#
# In my opinion it is much better to be explicit and block the specific
# segments we want blocked.
#
# Bloque les ordinateurs depuis l&#39;interface réseau DMZ essayant d&#39;atteindre
# les autres sur les deux autres segments réseaux
block drop in on $dmz to { $g_lan:network $c_lan:network }

# En dernier, autorisons les paquets à sortir s&#39;ils viennent de l&#39;interface
# réseau DMZ vers les ordinateurs attachés, autrement pas de &#34;discussion&#34;.
# Sans cela nous ne pouvons même pas pinguer les ordinateurs attachés à
# l&#39;interface réseau DMZ depuis le routeur lui-même
pass out on $dmz inet keep state
</code></pre><p>Maintenant, occupons nous de la NAT.
C&rsquo;est là où le routeur route les paquets venant d&rsquo;un segment du réseau
vers un autre, dans le cas spécifique venant de notre réseau interne vers
Internet, et alors toute réponse venant d&rsquo;Internet, à destination de
l&rsquo;initiateur de la transmission.
Je préfère le paramètre <code>:network</code> qui traduit le(s) réseau(x)
attaché(s) à l&rsquo;interface, et je préfère être spécifique avec une règle
pour chaque segment concerné.</p>
<pre tabindex="0"><code>#---------------------------------#
# NAT
#---------------------------------#

pass out on $ext_if inet from $g_lan:network to any nat-to ($ext_if)
pass out on $ext_if inet from $c_lan:network to any nat-to ($ext_if)
pass out on $ext_if inet from $dmz:network to any nat-to ($ext_if)
</code></pre><p>PF gardera une trace de tout le trafic, et quand, e.g. un navigateur web sur
le LAN Adultes demandera une page web de certains sites sur Internet,
la réponse venant du serveur web depuis Internet sera routé au-travers de
l&rsquo;interface externe vers l&rsquo;interface interne du LAN Adultes, et alors
directement vers le PC qui a initié la requête.</p>
<p>Enfin, occupons-nous de la partie relative à la redirection dans notre
jeu de règles.
C&rsquo;est là où nous permettons le trafic venant d&rsquo;Internet vers notre serveur
web publique sur l&rsquo;interface réseau DMZ.
Vous devriez, bien sûr, laisser cette partie si vous n&rsquo;avez pas de serveurs
publiques qui nécessitent de redirection.
Dans cet exemple, j&rsquo;ai seulement permis le trafic IPv4.</p>
<pre tabindex="0"><code>#---------------------------------#
# Redirects
#---------------------------------#

# Our web server - let the Internet access it.
pass in on $ext_if inet proto tcp to $ext_if port { 80 443 } rdr-to 192.168.3.2
</code></pre>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">La redirection arrive toujours en dernier dans le jeu de règles !</div>

<p>C&rsquo;est tout concernant le paramétrage basique de nos règles filtrantes.</p>
<h4 id="une-liste-blanche-pour-les-enfants">Une liste blanche pour les enfants</h4>
<p>Si vous voulez bloquer tout Internet pour les enfants, exceptés peut être
quelques sites web ou certains serveurs de jeux, vous avez besoin de
connaître quelles adresses IP ces services ont et de créer une liste
blanche utilisant ces adresses IP.</p>
<p>Si c&rsquo;est un simple site web avec une adresse IP unique, c&rsquo;est très facile
et vous pouvez le faire avec cette règle placée en dernier dans le bloc
pour enfants (vous devez remplacer la partie x.x.x.x avec l&rsquo;adresse IP
pertinente) :</p>
<pre tabindex="0"><code>#---------------------------------#
# Childrens LAN Setup
#---------------------------------#

# Allow any computer or device attached to the childrens NIC to get an IP
# address from DHCP on the router.
pass in on $c_lan inet proto udp from any port 67

# Allow any computer or device attached to the childrens NIC to make DNS
# queries.
pass in on $c_lan inet proto udp from any port 53

# Always block DNS queries not addressed to our DNS server.
block return in quick on $c_lan proto { udp tcp} to ! $c_lan port { 53 853 }

# Then allow any computer or device attached on the childrens LAN to reach
# the IP address x.x.x.x only.
pass in on $c_lan to x.x.x.x
</code></pre><p>Si le site web a de multiples adresses IP, nous devons comprendre lesquelles.
Parfois une requête de nom de domaine peut révéler toutes les adresses IP
concernées en une fois.
D&rsquo;autres fois, nous avons besoin de répéter de multiples fois les requêtes
à différentes intervalles de la journée avant d&rsquo;obtenir l&rsquo;ensemble complet
des adresses IP.
Vous pouvez faire cela en mettant en place un script automatisé.</p>
<p>Parfois, nous aurons besoin de contacter l&rsquo;entreprise en question et de
demander si nous pouvons avec l&rsquo;ensemble des adresses IP pour notre liste
blanche (certaines compagnies publient publiquement l&rsquo;information, d&rsquo;autres
refusent de livrer l&rsquo;information par peur d&rsquo;un usage malicieux).
Une fois que vous avez déterminé quel est l&rsquo;ensemble d&rsquo;adresses IP, vous
pouvez faire une <code>table</code> PF pour l&rsquo;utiliser.</p>
<p>Dans cet exemple, nous ajoutons une nouvelle table dans la section table
des règles et nous changeons les paramètres des règles pour enfants.</p>
<pre tabindex="0"><code>#---------------------------------#
# Tables
#---------------------------------#

…

# Whitelist for the children.
table &lt;whitelist&gt; { x.x.x.x y.y.y.y z.z.z.z }
</code></pre><p>Et ensuite dans la section pour enfants, changez :</p>
<pre tabindex="0"><code>pass in on $c_lan to x.x.x.x
</code></pre><p>en :</p>
<pre tabindex="0"><code>pass in on $c_lan to &lt;whitelist&gt;
</code></pre><p>Il n&rsquo;est pas toujours possible d&rsquo;avoir toutes les adresses IP dans une
liste blanche en une fois, mais en surveillant le réseau, en utilisant e.g.
<a href="https://man.openbsd.org/tcpdump" rel="external">tcpdump</a>, quand le jeu essaye d’accéder
au serveur, vous pouvez établir une liste, bit après bit.
J&rsquo;ai fait cela avec les serveurs de connexion Mojan et Minecraft et de
multiples autres serveurs de jeux.</p>
<h5 id="utilisation-dune-table-persistante">Utilisation d&rsquo;une table persistante</h5>
<p>Une autre approche pour collecter les IP est d&rsquo;utiliser une <a href="https://man.openbsd.org/pf.conf#TABLES" rel="external">table persistante</a>
en combinaison avec <code>/etc/rc.local</code> et les requêtes de noms de domaine.
<code>/etc/rc.local</code> est seulement exécuté <strong>après</strong> que PF soit démarré ainsi
les problèmes de résolution de DNS n&rsquo;entraîneront pas des problèmes pour
PF.</p>
<p>Si vous souhaitez utiliser la solution des tables persistantes, vous pouvez
le faire en ajoutant une table persistante dans la section des tables
dans <code>/etc/pf.conf</code> :</p>
<pre tabindex="0"><code>table &lt;whitelist&gt; persist
</code></pre><p>Dans la section pour enfants, nous avons besoin de passer les données
qui viennent de la liste blanche ci-dessus :</p>
<pre tabindex="0"><code>pass in on $c_lan to &lt;whitelist&gt;
</code></pre><p>Alors, dans <code>/etc/rc.local</code>, nous pouvons ajouter la commande suivante :</p>
<pre tabindex="0"><code>pfctl -t whitelist -T add example.com
</code></pre><p>Où <code>example.com</code> est le domaine que PF doit chercher.</p>
<p>Quand vos enfants ne peuvent pas avoir accès parce que l&rsquo;adresse IP valide
pourrait avoir changé, vous pouvez vous connecter au pare-feu et alors
mettre à jour manuellement la table avec plus d&rsquo;adresses IP en exécutant
la commande :</p>
<pre tabindex="0"><code>pfctl -t whitelist -T add examples.com
</code></pre><p>Si vous voulez voir ce qui a été ajouté à cette liste, vous pouvez faire
ceci :</p>
<pre tabindex="0"><code># pfctl -t whitelist -T show
74.6.143.25
74.6.143.26
74.6.231.20
74.6.231.21
98.137.11.163
98.137.11.164
216.58.208.110
2001:4998:24:120d::1:0
2001:4998:24:120d::1:1
2001:4998:44:3507::8000
2001:4998:44:3507::8001
2001:4998:124:1507::f000
2001:4998:124:1507::f001
2a00:1450:400e:80e::200e
</code></pre><p>Éventuellement, vous pouvez ajouter toutes les adresses IP que vous collectez
(avant qu&rsquo;elles ne soient purgées) dans un fichier physique afin que l&rsquo;option
<code>persist</code> prenne en entrée ce fichier, tel que :</p>
<pre tabindex="0"><code>table &lt;whitelist&gt; persist file &#34;/etc/pf-whitelist.txt&#34;
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Le fichier ne devra pas avoir d&rsquo;adresses IP ajoutées en utilisant
l&rsquo;option <code>add</code> à <code>pfctl</code>.
Une table persistante réside soit en mémoire, soit dans un fichier, mais
l&rsquo;option <code>add</code> ne peut écrire sur le disque, seulement dans la mémoire.
Une table persistante depuis un fichier est ce dont vous avez besoin afin
de l&rsquo;éditer manuellement depuis un éditeur de texte.</div>

<h3 id="chargement-des-règles">Chargement des règles</h3>
<p>Une fois que vous avez fini de paramétrer votre jeu de règles, vous pouvez
le tester avec :</p>
<pre tabindex="0"><code># pfctl -nf /etc/pf.conf
</code></pre><p>Si tout est bon, chargez votre jeu de règles en supprimant l&rsquo;option <code>-n</code> :</p>
<pre tabindex="0"><code># pfctl -f /etc/pf.conf
</code></pre><p>Regardez le résultat traduit avec :</p>
<pre tabindex="0"><code># pfctl -s rules
</code></pre><h3 id="journalisation-et-monitoring">Journalisation et Monitoring</h3>
<p>Ceci est un exemple de sortie venant du journal de PF des essais bloqués
accédant à l&rsquo;interface externe, selon mon paramétrage. J&rsquo;ai nettoyé la
sortie et supprimé quelques données spécifiques, et bien sûr 0.0.0.0 n&rsquo;est
pas mon adresse IP publique, mais vous savez déjà cela ;)</p>
<pre tabindex="0"><code># tcpdump -n -e -ttt -r /var/log/pflog
23:11:12 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3422: S 1501043655:1501043655(0) win 1024
23:11:12 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3481: S 311078394:311078394(0) win 1024
23:11:31 rule 14/(match) block in on em0: 176.214.44.229.25197 &gt; 0.0.0.0.23: S 2084440900:2084440900(0) win 33620
23:11:33 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3431: S 2774981044:2774981044(0) win 1024
23:11:43 rule 14/(match) block in on em0: 81.68.114.52.17191 &gt; 0.0.0.0.23: S 1346864438:1346864438(0) win 26375
23:12:08 rule 14/(match) block in on em0: 193.27.229.26.53865 &gt; 0.0.0.0.443: S 1057596009:1057596009(0) win 1024
23:12:31 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.4186: S 1233742605:1233742605(0) win 1024
23:12:44 rule 14/(match) block in on em0: 74.120.14.70.65509 &gt; 0.0.0.0.9125: S 1836577847:1836577847(0) win 1024 &lt;mss 1460&gt; [tos 0x20]
23:12:44 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.4128: S 2112968453:2112968453(0) win 1024
23:13:15 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3669: S 3627248539:3627248539(0) win 1024
23:13:19 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3654: S 3889665614:3889665614(0) win 1024
23:13:29 rule 14/(match) block in on em0: 45.129.33.129.42239 &gt; 0.0.0.0.4997: S 2249816896:2249816896(0) win 1024
23:13:37 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3612: S 3797528151:3797528151(0) win 1024
23:14:03 rule 14/(match) block in on em0: 190.207.89.17.64372 &gt; 0.0.0.0.445: S 1097568353:1097568353(0) win 8192 &lt;mss 1460,nop,wscale 2,nop,nop,sackOK&gt; (DF)
23:14:15 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.4219: S 2834775769:2834775769(0) win 1024
23:14:39 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.3702: S 1855726637:1855726637(0) win 1024
23:14:39 rule 14/(match) block in on em0: 45.129.33.4.45980 &gt; 0.0.0.0.4210: S 3052103070:3052103070(0) win 1024
</code></pre><p>Comme vous pouvez le voir, il est un peu occupé, d&rsquo;autant que je n&rsquo;ai rien
en cours d&rsquo;exécution qui soit publiquement sur Internet dans ce paramétrage.</p>
<p>Vous pouvez aussi monitorer PF en temps réel avec :</p>
<pre tabindex="0"><code># tcpdump -n -e -ttt -i pflog0
</code></pre><h2 id="dns">DNS</h2>
<p><a href="https://fr.wikipedia.org/wiki/Domain_Name_System" rel="external">DNS (Domain Name Service)</a>
est utilisé pour traduire un nom de domaine dans une adresse IP ou vice-versa.
Par exemple, quand vous écrivez <a href="https://wikipedia.org/" rel="external">wikipedia.org</a>
dans la barre d&rsquo;adresse de votre navigateur web, un serveur DNS faisant
autorité traduit le nom de domaine &ldquo;wikipedia.org&rdquo; en une adresse IPv4,
telle que 91.198.174.192, et/ou une adresse IPv6, telle que 2620:0:862:ed1a::1.</p>
<p>DNS est aussi utilisé, en plus d&rsquo;autres choses, pour stocker des informations
sur les serveurs de messagerie appartenant à un nom de domaine particulier,
le cas échéant.</p>
<p>Si vous utilisez un système d&rsquo;exploitation de type UNIX, vous pouvez
démarrer un terminal et essayer de faire une recherche manuelle de nom
de domaine avec <code>host</code> :</p>
<pre tabindex="0"><code>$ host wikipedia.org
wikipedia.org has address 91.198.174.192
wikipedia.org has IPv6 address 2620:0:862:ed1a::1
wikipedia.org mail is handled by 10 mx1001.wikimedia.org.
wikipedia.org mail is handled by 50 mx2001.wikimedia.org.
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si <code>host</code> n&rsquo;est pas installé, ce qui dépend de votre plateforme, vous aurez
besoin d&rsquo;installer <a href="https://www.isc.org/bind/" rel="external">bind</a> ou <code>dnsutils</code>.
Vous pouvez aussi utiliser quelque chose comme <a href="https://man.openbsd.org/dig" rel="external">dig</a>,
qui vient de <a href="https://www.isc.org/bind/" rel="external">bind</a>, ou <a href="https://linux.die.net/man/1/drill" rel="external">drill</a>
venant de <a href="https://nlnetlabs.nl/projects/ldns/about/" rel="external">ldns</a>.</div>

<p>La liste qui suit décrit certains des termes associés à DNS :</p>
<ul>
<li>
<p><code>Forward DNS</code></p>
<ul>
<li>Correspondance des noms d&rsquo;hôtes ou de domaines avec les adresses IP.</li>
</ul>
</li>
<li>
<p><code>Reverse DNS</code></p>
<ul>
<li>Correspondance des adresses IP avec les noms d&rsquo;hôtes ou de domaines.</li>
</ul>
</li>
<li>
<p><code>Resolver</code></p>
<ul>
<li>Un système par lequel une machine requiert un serveur de nom pour
la zone d&rsquo;information, i.e. un autre nom pour &ldquo;Serveur DNS&rdquo;.</li>
</ul>
</li>
<li>
<p><code>Root zone</code></p>
<ul>
<li>Le début de la hiérarchie des zones Internet. Toutes les zones sont
sous la <a href="https://en.wikipedia.org/wiki/DNS_root_zone" rel="external">zone racine</a>,
similaire à ce que sont tous les fichiers dans un système de fichier
sous la hiérarchie racine /.</li>
</ul>
</li>
</ul>
<p>Ceci est un exemple de zone :</p>
<ul>
<li><code>.</code> (un point) est la manière dont la zone racine est habituellement
référée dans la documentation.</li>
<li><code>org.</code> est le <a href="https://fr.wikipedia.org/wiki/Domaine_de_premier_niveau" rel="external">TLD (Top-Level Domain)</a>
sous la zone root.</li>
<li><code>wikipedia.org.</code> est la zone sous le TLD <code>org.</code>.</li>
<li><code>1.168.192.in-addr.arpa</code> est la zone référençant toutes les adresses IP
qui sont dans l&rsquo;espace d&rsquo;adresse IP <code>192.168.1.*</code>.</li>
</ul>
<p>Quand un ordinateur sur Internet a besoin de résoudre un nom de domaine,
le résolveur découpe le nom dans ses labels de la droite vers la gauche.
Le premier composant, le TLD, est demandé en utilisant un serveur racine
pour obtenir le serveur faisant autorité responsable.
Les requêtes pour chaque label retournent des serveurs de noms plus
spécifiques jusqu&rsquo;à ce qu&rsquo;un serveur de noms renvoie la réponse à la
requête originale.</p>
<p>Même si un serveur DNS local peut implémenter ses propres serveurs de noms
racines privés, le terme &ldquo;serveur racine de noms&rdquo; est utilisé pour décrire
<a href="https://fr.wikipedia.org/wiki/Serveur_racine_du_DNS#Les_serveurs_racine_du_DNS" rel="external">les 13 serveur racines de noms bien connus</a>
qui mettent en œuvre le domaine de l&rsquo;espace racine des noms pour la mise
en œuvre mondiale officielle du système de noms de domaine d&rsquo;Internet.
Les résolveurs utilisent un petit fichier nommé <code>root.hints</code> de 3 Ko,
publié par <a href="https://fr.wikipedia.org/wiki/InterNIC" rel="external">Internic</a> pour amorcer
cette liste initiale d&rsquo;adresses des serveurs racines.
Pour beaucoup de logiciels, incluant Unbound, cette liste est intégrée à
l&rsquo;intérieur du logiciel.</p>
<p>Sur la <a href="https://www.iana.org/domains/root/db" rel="external">base de données de la zone racine</a>,
vous pouvez chercher les détails de délégation des domaines TLD, incluant
des TLD tels que .com, .org, et des TLD ayant des codes de pays, tels que
.uk, .de.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Puisque vous pouvez chercher les détails de délégation des domaines TLD,
vous pourriez vous attendre à ce qu&rsquo;il soit possible d&rsquo;aller en profondeur
et de chercher actuellement pour chaque domaine un serveur de domaine
en particulier qui a enregistré dans sa base de données.
Puisque nous avons, pour l&rsquo;exemple, pris une liste des serveurs de noms
TLD responsables pour le TLD <a href="https://www.iana.org/domains/root/db/dk.html" rel="external">.dk</a>,
nous pourrions nous attendre à ce qu&rsquo;il soit possible d&rsquo;interroger l&rsquo;un de
ces serveurs de noms listés pour l&rsquo;ensemble de la base de données des
serveurs faisant autorité, puis d&rsquo;interroger l&rsquo;un d&rsquo;entre eux pour tous
les domaines enregistrés dans sa base de données.
Mais ce n&rsquo;est pas comme cela que fonctionne DNS.
Il y a seulement deux manières pour obtenir la cartographie complète des
serveurs DNS.
Soit vous avez accès aux fichiers de la zone concernée, soit vous avez
besoin de construire physiquement une base de donnée en examinant le trafic
DNS au-travers un serveur DNS récursif et alors de reconstituer les données
de la zone à partir des données recueillies, jusqu&rsquo;à ce que vous obteniez
tout, ce qui est très peu probable.</div>

<p>Il y a deux types de configuration de serveur DNS :</p>
<ul>
<li>
<p><code>Autorité</code></p>
<ul>
<li>[Les serveurs de noms faisant autorité] publie les adresses pour les
domaines sous leur contrôle. Ces serveurs sont listés au début de la
chaîne d&rsquo;autorité pour leurs domaines respectifs, et sont capables de
fournir une réponse définitive. <br>
Les serveurs de noms faisant autorité peuvent être les serveurs de noms
primaires, connus aussi en tant que serveurs maîtres, i.e. ils contiennent
le jeu original des données, ou être des serveurs de noms secondaires
ou esclaves, contenant des copies des données habituellement obtenues
par synchronisation directe avec le serveur primaire. <br>
Un serveur de nom faisant autorité est un serveur de nom qui donne
seulement des réponses aux requêtes DNS venant de données qui ont été
configurées par une source originale, par exemple, l&rsquo;administrateur
de domaine. <br>
Chaque zone DNS doit être assignée à un ensemble de serveurs de noms
faisant autorité.
Cet ensemble de serveurs est enregistré dans la zone de domaine parente
des enregistrements du serveur de noms (NS).
Un serveur faisant autorité indique son statut de fournisseur de
réponses définitives, considérées comme faisant autorité, en posant
un drapeau de protocole, appelé bit &ldquo;Authoritative Answer&rdquo; (AA), dans
ses réponses. <br>
Vous pouvez utiliser un outil réseau, tel que <a href="https://man.openbsd.org/dig" rel="external">dig</a>
ou <a href="https://linux.die.net/man/1/drill" rel="external">drill</a> pour interroger un nom
de domaine ; l&rsquo;outil répondra avec un drapeau faisant autorité qui
révèle si le serveur DNS vous avez interrogé est celui qui fait autorité.</li>
</ul>
</li>
<li>
<p><code>Récursif</code></p>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Domain_Name_System" rel="external">Les serveurs récursifs</a>
parfois appelés &ldquo;DNS caches&rdquo; ou &ldquo;serveurs de noms de cache seulement&rdquo;
fournissent la résolution de noms DNS pour les applications, en relayant
les requêtes de l&rsquo;application cliente vers la chaîne des serveurs de
noms faisant autorité afin de résoudre pleinement un nom de domaine.
(Typiquement) ils mettent en cache le résultat pour répondre a de
futures requêtes potentielles dans une certaine période de temps avant
expiration. <br>
La plupart des utilisateurs d&rsquo;Internet accèdent à un serveur DNS récursif
publique fournit par leur FAI ou un fournisseur de service DNS publique. <br>
En théorie, les serveurs de noms faisant autorité sont suffisant pour
opérer sur Internet.
Toutefois, avec seulement les serveurs de noms faisant autorité opérant,
chaque requête DNS doit démarrer avec des requêtes successives à la
zone racine du système de nom de domaine et chaque utilisateur système
devrait avoir à implémenter un logiciel résolveur capable d&rsquo;opérations
de résolution.
Pour améliorer l&rsquo;efficacité, réduire le trafic DNS sur Internet, et
augmenter la performance des applications utilisateurs, le système de
noms de domaine prend en charge les résolveurs récursifs. <br>
Une requête d&rsquo;un DNS récursif est celle pour laquelle un serveur DNS
répond complètement à la requête en interrogeant d&rsquo;autres serveurs
de noms, selon ses besoins.</li>
</ul>
</li>
</ul>
<p>Un serveur de noms peut être à la fois faisant autorité et récursif, mais
il n&rsquo;est pas recommandé de combiner la configuration des deux types.
Pour être en mesure d&rsquo;effectuer leur travail, les serveurs faisant autorité
doivent être disponibles à tous les clients, tout le temps.
D&rsquo;un autre côté, étant donné que la requête récursive prend plus de temps
qu&rsquo;une réponse faisant autorité, les serveurs récursifs devraient être
restreints à un nombre de clients seulement, car ils sont enclins à des
<a href="https://fr.wikipedia.org/wiki/Attaque_par_d%C3%A9ni_de_service" rel="external">attaques par déni de service distribué (DDoS)</a>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si besoin, je vous recommande de lire &ldquo;How DNS Works&rdquo; du
<a href="https://tldp.org/LDP/nag2/x-087-2-resolv.howdnsworks.html" rel="external">chapitre 6 du Guide de l&rsquo;Administrateur Réseau Linux</a>.
Je recommande aussi de lire l&rsquo;article <a href="https://fr.wikipedia.org/wiki/Domain_Name_System" rel="external">DNS</a> sur Wikipédia.</div>

<h3 id="je-vous-présente-unbound">Je vous présente Unbound</h3>
<p><a href="https://nlnetlabs.nl/projects/unbound/about/" rel="external">Unbound</a> est un résolveur
DNS Open Source récursif, cache et validant avec les fonctionnalités
suivantes :</p>
<ul>
<li>Cache avec possibilité de récupèrer des éléments populaires avant qu&rsquo;ils
expirent.</li>
<li>Serveur et Redirection DoT (DNS over TLS), avec validation de domaine</li>
<li>DoH (DNS over HTTPS)</li>
<li>Minimisation du nom de la requête</li>
<li>Utilisation aggressive du cache validé par DNSSEC.</li>
<li>Zones faisant autorité, pour une copie locale de la zone racine.</li>
<li>DNS64</li>
<li>DNSCrypt</li>
<li>Validation DNSSEC</li>
<li>Client de sous-réseau EDNS</li>
</ul>
<p>Unbound est conçu pour être rapide et sécurisé et incorpore des fonctionnalités
modernes basées sur des normes ouvertes. Fin 2019, Unbound a été
<a href="https://ostif.org/wp-content/uploads/2019/12/X41-Unbound-Security-Audit-2019-Final-Report.pdf" rel="external">rigoureusement audité</a>.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Une des principales raisons d&rsquo;utiliser Unbound plutôt que de nombreux autres
résolveurs cache seulement, tel que <a href="https://fr.wikipedia.org/wiki/Dnsmasq" rel="external">dnsmasq</a>
par exemple, est que si vous n&rsquo;utilisez pas l&rsquo;option <strong>forward</strong> dans la
configuration d&rsquo;Unbound, Unbound <strong>fera des requêtes directement aux serveurs
racines</strong> en utilisant leurs adresses IP enregistrées et listées dans le
<a href="https://www.iana.org/domains/root/files" rel="external">fichier Root Hints</a>.
Ceci vous libèrera des serveurs DNS de votre FAI, et de tout serveur DNS
publique, tel que Google ou Cloudflare, et tout enregistrement, vente et
manipulation de données, tels qu&rsquo;ils le font sera évité.
Un simple serveur cache tel que dnsmasq devra toujours rediriger ses requêtes
vers un autre serveur, là où Unbound interrogera les serveurs racines
directement et suivra la chaîne des domaines jusqu&rsquo;à ce qu&rsquo;il obtienne
l&rsquo;enregistrement pertinent depuis le serveur DNS faisant autorité pour le
domaine concerné.
Cela signifie que le serveur DNS qui sait spécifiquement ce que vous
recherchez soit aussi celui qui fait autorité pour répondre à la question.</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si votre FAI fait du détournement de trafic DNS, Unbound ne vous aidera
en aucune manière.
Lisez la section <a href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#détournement-de-dns">Détournement de DNS</a> concernant
l&rsquo;information afin que vous puissiez déterminer sir le trafic
de votre DNS est détourné.</div>

<p>Dans notre paramétrage avec Unbound, une requête pour un domaine tel que
&ldquo;wikipedia.org&rdquo; ressemblera à ceci :</p>
<ol>
<li>Votre navigateur envoie une requête au système d&rsquo;exploitation, avec
la question &ldquo;Quelle est l&rsquo;adresse IP de wikipedia.org ?&rdquo;</li>
<li>Le système d&rsquo;exploitation, plus spécifiquement les routines du résolveur
dans la bibliothèque C, qui fournit l&rsquo;accès au Système de Noms de Domaines
sur Internet, redirigera la requête DNS vers le(s) serveur(s) de noms de
domaine listé dans <a href="https://man.openbsd.org/resolv.conf" rel="external">/etc/resolv.conf</a>
(sur des systèmes d&rsquo;exploitation de type UNIX)</li>
<li>Unbound reçoit la requête et en premier cherche &ldquo;wikipedia.org&rdquo; dans son
cache et s&rsquo;il ne le trouve pas, interroge un des serveurs racines listés
dans son fichier Root Hints pour le domaine TLD &ldquo;.org&rdquo;.</li>
<li>Le serveur racine répond par une référence aux serveurs concernés du
domaine TLD &ldquo;.org&rdquo;.</li>
<li>Unbound envoie alors une requête à l&rsquo;un des serveurs concernés demandant
quels sont les serveurs DNS faisant autorité pour &ldquo;wikipedia.org&rdquo;.</li>
<li>Le serveur répond avec une référence aux serveurs de noms faisant autorité
enregistrés pour &ldquo;wikipedia.org&rdquo;.</li>
<li>Unbound envoie alors une requête à l&rsquo;un des serveurs de noms faisant
autorité et demande l&rsquo;adresse IP pour &ldquo;wikipedia.org&rdquo;.</li>
<li>Le serveur de noms faisant autorité répond par l&rsquo;envoi de l&rsquo;adresse IP
listée dans les enregistrements &ldquo;A&rdquo; et/ou &ldquo;AAAA&rdquo; pour le domaine
&ldquo;wikipedia.org&rdquo;.</li>
<li>Unbound reçoit l&rsquo;adresse IP du serveur de noms faisant autorité et
retourne la réponse au client.</li>
<li>Si cela est activé, Unbound met en cache alors l&rsquo;information pour une
longueur de temps prédéterminée pour de futures requêtes pour le même nom
de domaine.</li>
</ol>
<p>Vous pouvez essayer de faire une <code>trace</code> DNS par vous-mêmes pour voir le
propos ci-dessus. J&rsquo;utilise <a href="https://linux.die.net/man/1/drill" rel="external">drill</a>
dans cet exemple avec l&rsquo;option <code>trace</code> activée.</p>
<pre tabindex="0"><code># drill -T wikipedia.org
.       518400  IN      NS      l.root-servers.net.
.       518400  IN      NS      k.root-servers.net.
.       518400  IN      NS      e.root-servers.net.
.       518400  IN      NS      a.root-servers.net.
.       518400  IN      NS      m.root-servers.net.
.       518400  IN      NS      h.root-servers.net.
.       518400  IN      NS      i.root-servers.net.
.       518400  IN      NS      f.root-servers.net.
.       518400  IN      NS      c.root-servers.net.
.       518400  IN      NS      b.root-servers.net.
.       518400  IN      NS      g.root-servers.net.
.       518400  IN      NS      d.root-servers.net.
.       518400  IN      NS      j.root-servers.net.
org.    172800  IN      NS      a0.org.afilias-nst.info.
org.    172800  IN      NS      a2.org.afilias-nst.info.
org.    172800  IN      NS      b0.org.afilias-nst.org.
org.    172800  IN      NS      b2.org.afilias-nst.org.
org.    172800  IN      NS      c0.org.afilias-nst.info.
org.    172800  IN      NS      d0.org.afilias-nst.org.
wikipedia.org.  86400   IN      NS      ns0.wikimedia.org.
wikipedia.org.  86400   IN      NS      ns1.wikimedia.org.
wikipedia.org.  86400   IN      NS      ns2.wikimedia.org.
wikipedia.org.  600     IN      A       91.198.174.192
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Unbound a la capacité de valider les réponses qu&rsquo;il reçoit comme correctes.
C&rsquo;est habituellement accompli par l&rsquo;utilisation de
<a href="https://fr.wikipedia.org/wiki/Domain_Name_System_Security_Extensions" rel="external">DNSSEC</a>
ou l&rsquo;utilisation de bits aléatoires encodés 0x20 dans la requête pour
déjouer les tentatives d&rsquo;usurpation d&rsquo;identité.
À l&rsquo;exception des <a href="https://man.openbsd.org/unbound.conf#use~3" rel="external">bits aléatoires encodés 0x20</a>,
tous les autres paramétres de validation tel que <a href="https://man.openbsd.org/unbound.conf#harden~3" rel="external">harden-glue</a>
et <a href="https://man.openbsd.org/unbound.conf#harden~4" rel="external">hardened dnssec-stripped data</a>
sont tous activés par défaut dans Unbound pour OpenBSD.</div>

<h3 id="blocage-par-dns">Blocage par DNS</h3>
<p>Le blocage par DNS, appelé aussi filtrage ou usurpation DNS, est le processus
qui vous permet de fournir une &ldquo;fausse&rdquo; réponse au client qui effectue
la requête.
Nous bloquons une requête pour une adresse IP valide soit en répondant avec
un <a href="https://tools.ietf.org/html/rfc8020" rel="external">NXDOMAIN</a>, signifiant nom de domaine
inexistant, ou soit en redirigeant vers une autre adresse IP que celle prévue
par le propriétaire du domaine.</p>
<p>Cela nous oblige à créer une liste, ou des listes multiples, de domaines
que nous voulons bloquer et plutôt que de fournir à l&rsquo;utilisateur l&rsquo;adresse
IP correcte pour un certain domaine, nous renvoyons le message que le
domaine est &ldquo;inexistant&rdquo;, ce qui bloquera toute communication vers la
destination prévue pour l&rsquo;application.</p>
<p>Normalement, toutes les requêtes DNS sont envoyés vers le port 53 soit sur
le protocole UDP, soit TCP, lors de la mise en place du serveur DNS, ce que
nous faisons avec Unbound, et en s&rsquo;assurant que tout le trafic du port 53
atteigne notre serveur DNS ou autrement soit bloqué ; nous pouvons nous
assurer que toutes les réponses DNS viennent de notre serveur Unbound interne
à notre routeur OpenBSD.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Vous ne pouvez pas pleinement faire confiance au blocage par DNS car le
blocage par DNS peut être contourné.
Même en ayant une solide approche en place, il est toujours possible pour
quelqu&rsquo;un d&rsquo;utiliser un <a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_priv%C3%A9_virtuel" rel="external">service VPN</a>
pour contourner cela.
Nous n&rsquo;essayons pas de construire un système 100% infaillible - même si
nous y reviendrons un peu plus loin dans ce guide - nous essayons juste
de protéger nos familles de la meilleure manière.
Il y a toujours aussi les autres points d&rsquo;accès à Internet que nous devons
considérer, tels que les téléphones, ceux des amis ou leur maison, les
accès publique à Internet, etc.</div>

<h4 id="nxdomain-vs-redirection">NXDOMAIN vs redirection</h4>
<p>Quand nous voulons bloquer un domaine en utilisant DNS, nous pouvons choisir
entre différentes méthodes, mais les deux plus populaires sont soit de
rediriger la requête DNS vers une adresse IP locale, tel que 127.0.0.1 ou
0.0.0.0, ou de répondre par une définition NXDOMAIN.
NXDOMAIN est une norme de réponse pour un &ldquo;nom de domaine Intranet ou
Internet non existant&rdquo;.
Si le nom de domaine est incapable d&rsquo;être résolu en utilisant DNS, une
condition appellée NXDOMAIN est obtenue.</p>
<p>Nous pouvons essayer de résoudre un domaine non existant avec la commande
<code>host</code> :</p>
<pre tabindex="0"><code>$ host a1b7c3n9m3b0.com
Host a1b7c3n9m3b0.com not found: 3(NXDOMAIN)
</code></pre><p>Puisque le nom de domaine &ldquo;a1b7c3n9m3b0.com&rdquo; n&rsquo;est enregistré par personne
(au moins pas durant le temps où j&rsquo;écris cela), nous obtenons une réponse
&ldquo;NXDOMAIN&rdquo;.</p>
<p>Nous pouvons aussi utiliser <code>drill</code>. L&rsquo;information pertinente depuis la
sortie de <code>drill</code> est le champ <code>rcode</code> dans la section &ldquo;HEADER&rdquo; :</p>
<pre tabindex="0"><code>$ drill a1b7c3n9m3b0.com
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NXDOMAIN, id: 39710
…
</code></pre><p>Ou si vous préférez <code>dig</code>, alors l&rsquo;information pertinente est localisée
dans le champ <code>status</code> dans la section &ldquo;HEADER&rdquo; :</p>
<pre tabindex="0"><code>$ dig a1b7c3n9m3b0.com

; &lt;&lt;&gt;&gt; DiG 9.16.8 &lt;&lt;&gt;&gt; +search a1b7c3n9m3b0.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NXDOMAIN, id: 48858
…
</code></pre><p>Utiliser une réponse NXDOMAIN n&rsquo;est pas seulement la manière correcte de
bloquer un domaine, en accord avec la <a href="https://tools.ietf.org/html/rfc8020" rel="external">RFC8020</a>,
mais c&rsquo;est aussi la meilleure manière de le faire puisque une redirection
vers une adresse IP, telle que 127.0.0.1 ou 0.0.0.0 fera simplement que
le client qui initie la requête DNS se parlera à lui-même.</p>
<p>Il se peut que le navigateur réponde avec quelque chose comme :
<code>Firefox can't establish a connection to the server at 0.0.0.0.</code>.
Toutefois, puisque l&rsquo;adresse IP 0.0.0.0 se traduit simplement  par notre
machine locale, nous pouvons toujours envoyé un ping à cette adresse, car
elle est synonyme d&rsquo;un ping à 127.0.0.1 :</p>
<pre tabindex="0"><code>$ ping 0.0.0.0
PING 0.0.0.0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.019 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.049 ms
</code></pre><p>Et puisque je recommande que vous utilisiez une réponse NXDOMAIN, c&rsquo;est
ce que nous allons utiliser dans ce tutoriel.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Unbound peut gérer des listes énormes de domaines bloqués avec une réponse
NXDOMAIN, mais il ne peut pas gérer de grandes listes de domaines qui ont
besoin d&rsquo;être redirigés aussi bien.
Si pour certaines raisons, vous devriez insister sur la redirection plutôt
que d&rsquo;utiliser NXDOMAIN, je vous recommande de paramétrer
<a href="http://www.thekelleys.org.uk/dnsmasq/doc.html" rel="external">dnsmasq</a>
avec l&rsquo;option <strong>&ndash;addn-hosts=&lt;file&gt;</strong>, pour qu&rsquo;il écoute le port 53 et
qu&rsquo;il redirige tous les domaines bloqués, pendant qu&rsquo;il redirige les requêtes
DNS normales vers Unbound. Cela demande de paramétrer Unbound afin d&rsquo;écouter
sur un port non standard, tel que le port 5353.
Contrairement à Unbound, dnsmasq peut gérer d&rsquo;énormes listes de redirection
très bien, mais il ne peut gérer de grandes liste de domaines NXDOMAIN
aussi bien, devenant extrêmement lent.</div>

<h3 id="le-problème-avec-dns-sur-https-doh">Le problème avec DNS sur HTTPS (DOH)</h3>
<p>Avec l&rsquo;introduction de <a href="https://fr.wikipedia.org/wiki/DNS_over_HTTPS" rel="external">DoH (DNS over HTTPS)</a>,
le blocage par DNS est devenu beaucoup plus difficile, et, bien que j&rsquo;ai
un certain respect pour l&rsquo;idée originale derrière la promotion de DoH du
point de vue de la confidentialité, DoH est mal construit d&rsquo;un point de
vue de la sécurité, et c&rsquo;est une <strong>MAUVAISE</strong> approche.</p>
<p>Avec le nombre déjà croissant de serveurs DNS publiques capable de servir
du DNS sur HTTPs, toute application peut maintenant utiliser DoH et
contourner complétement le blocage par DNS au niveau privé et entreprise.
Non seulement cela, mais DoH a ouvert une large porte pour les dévelopeurs
d&rsquo;application afin de paramétrer leurs propres serveurs DoH et de les
utiliser dans leurs applications au lieu du serveur DNS régulier attaché
au réseau interne.
C&rsquo;est spécifiquement un problème pour le
<a href="https://fr.wikipedia.org/wiki/Logiciel_propri%C3%A9taire" rel="external">logiciel propriétaire</a>
dont nous ne pouvons pas voir le code source, mais dont nous ne pouvons
pas aussi changer les paramétres DoH.</p>
<p>À cause de DoH, nous ne pouvons plus bloquer simplement des domaines, tels
que les publicitaires ou le porno, nous devons aussi commencer à bloquer
les serveurs DoH publiques via le pare-feu.
Toutefois, bien que garder une liste croissante d&rsquo;un nombre d&rsquo;adresses IP
de serveurs DoH publique soit assez problèmatique, garder une liste de
serveurs DoH publiques inconnus, qui peuvent être utilisé par du logiciel
propriétaire, tel que du micro-logiciel dans des dispositifs
<a href="https://fr.wikipedia.org/wiki/Internet_des_objets" rel="external">IoT</a>, est impossible.</p>
<p>DoH est aussi un complet cauchemard pour les entreprises car il rend
basiquement possible de surpasser les paramétres DNS imposés centralement.
Cela rend impossible de fournir des solutions de filtrage, telle que
celle que nous faisons, pour bloquer la publicité et le porno, et rend
impossible pour les administrateurs systèmes de surveiller les paramétres
DNS du système d&rsquo;exploitation afin de prévenir les attaques de
<a href="https://fr.wikipedia.org/wiki/Manipulation_de_l%27espace_des_noms_de_domaine" rel="external">manipulation DNS</a>.
Avoir de multiples applications qui ont leur unique paramétre DoH est un
cauchemar.</p>
<p>DoH gène complétement l&rsquo;analyse réseau et la surveillance du trafic DNS
à des fins de sécurité.
En 2019, Godlua, un bot Linux DDoS, était le premier
<a href="https://fr.wikipedia.org/wiki/Logiciel_malveillant" rel="external">logiciel malveillant</a>
vu à <a href="https://www.zdnet.com/article/first-ever-malware-strain-spotted-abusing-new-doh-dns-over-https-protocol/" rel="external">utiliser DoH pour cacher son trafic DNS</a>.</p>
<p>De plus, et c&rsquo;est peut-être l&rsquo;aspect le plus important, DoH <strong>n&rsquo;empêche
aucunément le suivi des utilisateurs</strong>.
Certaines parties de la connection HTTPS ne sont pas chiffrées, tels que
les <a href="https://fr.wikipedia.org/wiki/Server_Name_Indication" rel="external">champs SNI</a>
(mais on y arrive lentement), les <a href="https://fr.wikipedia.org/wiki/Online_Certificate_Status_Protocol" rel="external">connexions OCSP</a>,
et bien sûr <strong>les adresses IP de destination</strong>, ce qui à mon humble avis
est le point le plus crucial de la communication qui a besoin d&rsquo;être caché !</p>
<p>Les personnes qui ont vraiment besoin de confidentialité, tels que les
journalistes dans des pays ayant une politique de confidentialité compromise,
ne peuvent faire confiance à DoH !
L&rsquo;adresse IP du serveur de destination ne peut pas être caché avec DoH,
même si tout le trafic est lui-même chiffré.
Si quelqu&rsquo;un a vraiment besoin de chiffrer la communication, il a besoin
d&rsquo;une stratégie complétement différente de DoH.</p>
<p>Cela me fait me demander qui a pensé que DoH était une bonne idée au départ ?!
Ne comprennent-ils pas les bases derrière les communications avec HTTPS,
ou peut-être est-ce l&rsquo;agenda poussé par quelques entreprises privées de
service DNS, tel que Cloudflare, qui tire profit en collectant davantage
de données utilisateurs ?</p>
<p>Certains fournisseurs de service DNS publique status que d&rsquo;un point de vue
de la confidentialité, DoH est meilleur que d&rsquo;autres alternatives, telle
<a href="https://en.wikipedia.org/wiki/DNS_over_TLS" rel="external">DoT (DNS over TLS)</a>, puisque
les requêtes DNS sont cachées dans le large flux du trafic HTTPS.
Cela donne aux administrateurs réseaux moins de visibilité mais fournit
aux utilisateurs plus de confidentialité.</p>
<p>Ce message est problématique.
Bien qu&rsquo;il soit vrai que la recherche initiale d&rsquo;un nom de domaine soit
caché dans le trafic HTTPS, l&rsquo;adresse IP de destination fournit par le
serveur DoH ne l&rsquo;est pas.
Quand l&rsquo;application cliente visite l&rsquo;adresse IP de destination, les deux
adresses IP, celle de source et celle de destination, sont journalisées
au niveau du FAI (et possiblement à de multiples autres niveaux, aussi bien).</p>
<p>Bien qu&rsquo;il ne soit pas immédiatement possible de déterminer exactement
quel nom de domaine l&rsquo;utilisateur essaye d&rsquo;atteindre, spécifiquement si
le serveur web fait fonctionner de multiples domaines sur la même adresse
IP, ce n&rsquo;est définitivement pas impossible voire n&rsquo;est même pas difficile.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Dans l&rsquo;appendice, vous pouvez trouver un chapitre appellé
<a href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#inspecter-dns-sur-https-doh">Inspecter DNS sur HTTPS (DOH)</a>,
dans laquelle nous ferons une démonstration de comment l&rsquo;adresse IP de
destination est révélée dans la communication DoH.
Vous pouvez aussi trouver un chapitre appellé
<a href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/#bloquer-dns-sur-https-doh">Bloquer DNS sur HTTPS (DOH)</a> dans
laquelle nous utilisons le pare-feu PF pour bloquer les serveurs DoH publiques.</div>

<h3 id="paramétrage-dunbound">Paramétrage d&rsquo;Unbound</h3>
<h4 id="paramétrages-de-base">Paramétrages de base</h4>
<p>Paramètrer Unbound est très facile, car Unbound est fourni avec les meilleurs
paramètres par défaut, mais est aussi très bien documenté.
Avant que nous commencions, je vous recommande de regarder les pages des
manuels OpenBSD pour <a href="https://man.openbsd.org/unbound" rel="external">unbound</a>,
<a href="https://man.openbsd.org/unbound-checkconf" rel="external">unbound-checkconf</a>
et <a href="https://man.openbsd.org/unbound.conf" rel="external">unbound.conf</a>.</p>
<p>Du fait qu&rsquo;Unbound soit <a href="https://fr.wikipedia.org/wiki/Chroot" rel="external">chrooté</a>
sur OpenBSD, le fichier de configuration <code>unbound.conf</code> ne réside pas
dans <code>/etc</code>, là où il devrait être normalement, mais à la place réside
dans <code>/var/unbound/etc/</code>.</p>
<p>Copiez le fichier de configuration existant d&rsquo;Unbound :</p>
<pre tabindex="0"><code># mv /var/unbound/etc/unbound.conf /var/unbound/etc/unbound.conf.backup
</code></pre><p>Ensuite, utilisez votre éditeur texte favori et créer un nouveau fichier
<code>/var/unbound/etc/unbound.conf</code> et remplissez-le avec le contenu suivant :</p>
<pre tabindex="0"><code>server:

    # Logging (default is no).
    # Uncomment this section if you want to enable logging.
    # Note enabling logging makes the server (significantly) slower.
    # verbosity: 2
    # log-queries: yes
    # log-replies: yes
    # log-tag-queryreply: yes
    # log-local-actions: yes

    interface: 127.0.0.1
    interface: 192.168.1.1
    interface: 192.168.2.1
    interface: 192.168.3.1

    # In case you need Unbound to listen on an alternative port, this is the
    # syntax:
    # interface: 127.0.0.1@5353

    # Control who has access.
    access-control: 0.0.0.0/0 refuse
    access-control: ::0/0 refuse
    access-control: 127.0.0.0/8 allow
    access-control: ::1 allow
    access-control: 192.168.1.0/24 allow
    access-control: 192.168.2.0/24 allow
    access-control: 192.168.3.0/24 allow

    # &#34;id.server&#34; and &#34;hostname.bind&#34; queries are refused.
    hide-identity: yes

    # &#34;version.server&#34; and &#34;version.bind&#34; queries are refused.
    hide-version: yes

    # Cache elements are prefetched before they expire to keep the cache up to date.
    prefetch: yes

    # Our LAN segments.
    private-address: 192.168.0.0/16

    # We want DNSSEC validation.
    auto-trust-anchor-file: &#34;/var/unbound/db/root.key&#34;

# Enable the usage of the unbound-control command.
remote-control:
    control-enable: yes
    control-interface: /var/run/unbound.sock
</code></pre><p>J&rsquo;ai commenté les options ci-dessus, mais si vous avez besoin d&rsquo;explications
plus profondes concernant la configuration, regardez la page du manuel
<a href="https://man.openbsd.org/unbound.conf" rel="external">unbound.conf</a>.</p>
<p>La journalisation est faite par défaut vers syslog.
Si vous voulez changer cela, vous pouvez créer un fichier log dans le
chroot d&rsquo;Unbound et ainsi avoir le journal d&rsquo;Unbound :</p>
<pre tabindex="0"><code># mkdir /var/unbound/log
# touch /var/unbound/log/unbound.log
# chown -R root._unbound /var/unbound/log
# chmod -R 774 /var/unbound/log
</code></pre><p>Et, dans le fichier <code>unbound.conf</code>, ajoutez les options suivantes vers la
section de journalisation :</p>
<pre tabindex="0"><code>logfile: &#34;/log/unbound.log&#34;
use-syslog: no
log-time-ascii: yes
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Nous n&rsquo;utilisons pas le chemin complet du fichier de log parce qu&rsquo;Unbound
est chrooté.
Avec l&rsquo;option <code>logfile</code> ci-dessus, le fichier log se retrouve dans
<code>/var/unbound/log/unbound.log</code>.</div>

<p>Puis, redémarrez Unbound :</p>
<pre tabindex="0"><code># rcctl restart unbound
</code></pre><p>Dans les paramétres ci-dessus, j&rsquo;ai autorisé Unbound à écouter l&rsquo;interface
loopback (127.0.0.1) en premier afin que les applications réseaux locales
soient capables de faire des recherches si besoin.
Dans le fichier <code>etc/resolv.conf</code> de notre routeur OpenBSD, j&rsquo;ai listé
notre serveur DNS Unbound, car je ne veux rien sur le routeur qui interroge
les serveurs DNS du FAI :</p>
<pre tabindex="0"><code>nameserver 127.0.0.1
</code></pre><p>Si vous utilisez DHCP sur l&rsquo;interface externe (l&rsquo;interface connecté au
modem ou routeur de votre FAI), vous devez vous assurez que <a href="https://man.openbsd.org/dhclient" rel="external">dhclient</a>
ne change pas la configuration du fichier <code>/etc/resolv.conf</code>.
Éditez le fichier <code>/etc/dhclient.conf</code> et ajoutez :</p>
<pre tabindex="0"><code>supersede domain-name-servers 127.0.0.1;
</code></pre><p>Cela permettra de s&rsquo;assurer que nous avons notre serveur DNS local listé.</p>
<p>Activez Unbound avec :</p>
<pre tabindex="0"><code># rcctl enable unbound
</code></pre><p>Lorsque vous changez la configuration d&rsquo;Unbound, vous pouvez soit juste
redémarrer Unbound avec :</p>
<pre tabindex="0"><code># rcctl restart unbound
</code></pre><p>ou simplement recharger les options de configuration (ce qui purge aussi
le cache) :</p>
<pre tabindex="0"><code># unbound-control reload
</code></pre><p>Vous pouvez lister avec quels paramétres Unbound est démarré par la commande
suivante (qui est fourni pour tout service sous OpenBSD) :</p>
<pre tabindex="0"><code># rcctl get unbound
</code></pre><p>Si vous voulez avec certaines statitiques des données, vous pouvez exécuter :</p>
<pre tabindex="0"><code># unbound-control stats_noreset
thread0.num.queries=2056
thread0.num.queries_ip_ratelimited=0
thread0.num.cachehits=678
thread0.num.cachemiss=1378
thread0.num.prefetch=15
thread0.num.expired=0
…
</code></pre><p>Vous pouvez aussi avoir un dump du cache :</p>
<pre tabindex="0"><code># unbound-control dump_cache|less
</code></pre><p>Si vous voulez voir quelles sont les requêtes du serveur de nom Unbound
fait pour un domaine spécifique, vous pouvez faire cela avec :</p>
<pre tabindex="0"><code># unbound-control lookup wikipedia.org
</code></pre><p>Si vous voulez purger le cache pour un domaine spécifique, vous pouvez
faire cela avec :</p>
<pre tabindex="0"><code># unbound-control flush example.com
</code></pre><p>Prenez le temps de regarder la page du manuel d&rsquo;<a href="https://man.openbsd.org/unbound-control" rel="external">unbound-control</a>
pour les autres options et commandes.</p>
<h4 id="ignorer-les-réglages-ttl-ridiculeusement-bas">Ignorer les réglages TTL ridiculeusement bas</h4>
<p>Une chose qui crée une grande nuisance est le paramétrage de certaines
personnes sur des valeurs TTL ridiculeusement basses pour leurs domaines.
Pour certaines raisons, il est presque tendance d&rsquo;avoir une valeur par
défaut de 60 secondes.</p>
<p>Le problème avec un TTL très bas est que cela rend complétement inutile
le DNS cache.
Une requête utilisera seulement la réponse en cache aussi longtemps que
le TTL ne soit pas expiré.
Même au-travers des RFC qui disent qu&rsquo;un TTL doit être respecté, de telles
valeurs basses rend le DNS extrêmement inefficace.
Je recommande toutefois que vous surchargiez le paramétrage TTL par celui
d&rsquo;une heure par défaut.
Une autre amélioration dans la vitesse de requête de DNS est de réduire
la latence en se servant des enregistrements périmés avant de les mettre
à jour d&rsquo;une autre manière au lieu de faire l&rsquo;inverse.</p>
<pre tabindex="0"><code>cache-min-ttl: 3600
serve-expired: yes
</code></pre><p>Un problème théorique avec l&rsquo;augmentation du TTL est que le domaine pourrait
obtenir une nouvelle adresse IP qui ne peut pas être résolu puisque
l&rsquo;ancienne entrée est dans le cache.
Toutefois, dans la pratique le risque de fonctionner sur un domaine périmé
est minime et ça vaut la peine d&rsquo;améliorer l&rsquo;utilisation du cache en fixant
un TTL d&rsquo;une heure minimum par défaut.</p>
<h4 id="bloquons-certains-domaines-">Bloquons certains domaines !</h4>
<p>Maintenant, intéressons-nous à la partie du blocage de domaines.</p>
<p>J&rsquo;ai créé un simple script shell appelé <a href="https://codeberg.org/unixsheikh/dnsblockbuster" rel="external">DNSBlockBuster</a>
qui télécharge automatiquement un jeu de fichiers hosts depuis diverses
sources en-ligne, les concaténant ensemble en une seule, la nettoyant,
et convertissant le résultat en une liste de blocage de domaines pour
Unbound et dnsmasq.
Elle bloque principalement les publicités, les sites de porno et de pistage.</p>
<p>Avec DNSBlockBuster, vous avez l&rsquo;option de créer une liste blanche, si pour
vous l&rsquo;un des domaines listés dans les fichiers hosts est un faux positif,
et vous pouvez ajouter votre propre liste de blocage dans le cas où vous
voulez bloquer manuellement certains domaines qui ne sont pas listés dans
les fichiers hosts.
Vous pouvez facilement ajouter de nouvelles listes de blocage ou supprimer
l&rsquo;une des listes de blocage fournies.</p>
<p>Bien sûr, vous n&rsquo;avez pas besoin d&rsquo;utiliser mon script, mais je l&rsquo;utiliserais
dans ce tutoriel.</p>
<p>Actuellement le script créé une énorme liste de domaines avec plus de deux
millions de domaines listés et Unbound prend près de 705 Mo de mémoire au
total quand la liste de blocage est chargée en entier.</p>
<p>Afin d&rsquo;éviter qu&rsquo;Unbound tombe en panne lors du chargement de la liste,
éditez <code>/etc/rc.conf.local</code> et ajoutez ce qui suit :</p>
<pre tabindex="0"><code>unbound_timeout=240
</code></pre><p>Puis redémarrez Unbound :</p>
<pre tabindex="0"><code># rcctl restart unbound
</code></pre><p>Regardez la section <a href="https://codeberg.org/unixsheikh/dnsblockbuster#user-content-usage" rel="external">Usage</a>
dans la documentation de DNSBlockBuster pour savoir comment l&rsquo;utiliser.
C&rsquo;est simple et facile.</p>
<p>Une fois que vous avez créé votre liste de blocage pour Unbound, placez
la dans <code>/var/unbound/etc/</code> et éditez le fichier de configuration d&rsquo;Unbound
<code>/var/unbound/etc/unbound.conf</code> pour insérer quelque chose comme :</p>
<pre tabindex="0"><code>include: &#34;/var/unbound/etc/unbound-blocked-hosts.conf&#34;
</code></pre><p>Maintenant rechargez Unbound avec :</p>
<pre tabindex="0"><code># unbound-control reload
</code></pre><p>Si vous exécutez la commande <code>top</code> dans un autre terminal, vous remarquerez
qu&rsquo;Unbound consomme pas mal de ressources CPU lors du chargement initial
de la liste.
Remarquez aussi la consommation mémoire.</p>
<p>Vous pouvez maintenant tester notre blocage DNS en faisant une requête
vers un domaine bloqué de la liste :</p>
<pre tabindex="0"><code>$ drill 3lift.com
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NXDOMAIN, id: 55906
…
</code></pre><p>Essayez le même avec le serveur DNS de Cloudflare :</p>
<pre tabindex="0"><code>$ drill 3lift.com @1.1.1.1
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NOERROR, id: 48771
…
</code></pre><p>Comme nous pouvons le voir, notre serveur DNS bloque l&rsquo;accès au domaine
3lift.com en répondant avec un NXDOMAIN, alors que le serveur DNS de
Cloudflare répond avec l&rsquo;adresse IP correcte.</p>
<h3 id="sécurité-dns">Sécurité DNS</h3>
<p>La sécurité DNS est un vaste sujet.
Dans cette section, nous allons discuter de certains des sujets qui nous
concernent plus particulièrement à propos de notre propre serveur DNS.</p>
<p>Le protocole DNS n&rsquo;est pas chiffré et ne tient, par défaut, aucun compte
de la confidentialité, de l&rsquo;intégrité ou de l&rsquo;authentification.
Si vous utilisez un réseau non fiable, ou un FAI malveillant, vos requêtes
DNS peuvent être écoutées et les réponses manipulées.
En outre, les FAI peuvent procéder à des détournements de DNS.</p>
<h4 id="détournement-de-dns">Détournement de DNS</h4>
<p>Le détournement de DNS signifie que les requêtes DNS que vous faites sont
redirigées vers un autre serveur DNS.
C&rsquo;est typiquement fait en redirigeant tout le trafic sur le port 53 à
destination d&rsquo;un autre.</p>
<p>Un des manières les plus simples pour déterminer si votre FAI détourne
votre trafic DNS est d&rsquo;interroger directement un serveur DNS faisant autorité.</p>
<p>Nous pouvons utiliser de multiples outils pour cela.
Dans cet exemple, nous utiliserons en premier <code>drill</code>.
Ces options, dans cet exemple, sont les mêmes pour <code>dig</code>.
Nous utiliserons encore le domaine &ldquo;wikipedia.org&rdquo;.</p>
<p>En premier, nous avons besoin d&rsquo;avoir les serveurs faisant autorité.
Ils apparaîtront dans la section &ldquo;ANSWER SECTION&rdquo; :</p>
<pre tabindex="0"><code>$ drill NS wikipedia.org
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NOERROR, id: 28789
;; flags: qr rd ra ; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; wikipedia.org.       IN      NS

;; ANSWER SECTION:
wikipedia.org.  85948   IN      NS      ns2.wikimedia.org.
wikipedia.org.  85948   IN      NS      ns0.wikimedia.org.
wikipedia.org.  85948   IN      NS      ns1.wikimedia.org.

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 1 msec
;; SERVER: 127.0.0.1
;; WHEN: Thu Nov  5 07:53:19 2020
;; MSG SIZE  rcvd: 95
</code></pre><p>Alors nous devons interroger l&rsquo;un de ses serveurs faisant autorité directement.
Le champ important auquel nous devons faire attention est flags dans le
champ &ldquo;HEADER&rdquo;.
Pour que la réponse fasse autorité, le drapeau <code>aa</code> doit être listé.</p>
<pre tabindex="0"><code>$ drill @ns1.wikimedia.org wikipedia.org
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NOERROR, id: 57611
;; flags: qr aa rd ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; wikipedia.org.       IN      A

;; ANSWER SECTION:
wikipedia.org.  600     IN      A       91.198.174.192

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 127 msec
;; SERVER: 208.80.153.231
;; WHEN: Thu Nov  5 07:56:10 2020
;; MSG SIZE  rcvd: 47
</code></pre><p>Cela montre que la réponse que nous avons n&rsquo;a pas été détournée puisque
la réponse fait autorité.
Essayons de l&rsquo;obtenir depuis le serveur DNS publique de Cloudflare avec
la même requête :</p>
<pre tabindex="0"><code>$ drill @1.1.1.1 wikipedia.org
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, rcode: NOERROR, id: 40562
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; wikipedia.org.       IN      A

;; ANSWER SECTION:
wikipedia.org.  555     IN      A       91.198.174.192

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 3 msec
;; SERVER: 1.1.1.1
;; WHEN: Thu Nov  5 08:02:58 2020
;; MSG SIZE  rcvd: 47
</code></pre><p>Notez que le drapeau <code>aa</code> est manquant dans le champ &ldquo;HEADER&rdquo;.
Cela signifie que la réponse ne fait pas autorité.</p>
<p>Un autre outil simple est <a href="https://man.openbsd.org/nslookup" rel="external">nslookup</a>.
En premier interrogeons les serveurs de noms faisant autorité :</p>
<pre tabindex="0"><code>nslookup -querytype=NS wikipedia.org
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
wikipedia.org   nameserver = ns1.wikimedia.org.
wikipedia.org   nameserver = ns2.wikimedia.org.
wikipedia.org   nameserver = ns0.wikimedia.org.
</code></pre><p>Essayons alors d&rsquo;interroger notre propre serveur DNS pour le domaine :</p>
<pre tabindex="0"><code>$ nslookup wikipedia.org
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   wikipedia.org
Address: 91.198.174.192

Server:         ns2.wikimedia.org
Address:        91.198.174.239#53

Name:   wikipedia.org
Address: 91.198.174.192
</code></pre><p>Le message <code>Non-authoritative</code> montre clairement que la réponse n&rsquo;est pas
faite depuis un serveur DNS faisant autorité.
C&rsquo;est très bien, puisque nous avons interrogé notre propre serveur DNS.
Essayons d&rsquo;interroger un des serveurs faisant autorité directement :</p>
<pre tabindex="0"><code>$ nslookup wikipedia.org ns0.wikimedia.org
Server:         ns0.wikimedia.org
Address:        208.80.154.238#53

Name:   wikipedia.org
Address: 91.198.174.192
</code></pre><p>Le message <code>Non-authoritative</code> n&rsquo;est plus là, la réponse que nous avons
obtenu <strong>faisait autorité</strong>, ce qui signifie que notre requête DNS n&rsquo;a pas
été détournée.</p>
<p>J&rsquo;ai maintenant activé un service VPN que je connais pour intercepter les
requêtes DNS afin de protéger les clients contre la <a href="https://en.wikipedia.org/wiki/DNS_leak" rel="external">fuite DNS</a>
puis je fais une requête à nouveau vers les serveurs faisant autorité :</p>
<pre tabindex="0"><code>$ nslookup wikipedia.org ns0.wikimedia.org
Server:         ns0.wikimedia.org
Address:        208.80.154.238#53

Non-authoritative answer:
Name:   wikipedia.org
Address: 91.198.174.192
Name:   wikipedia.org
Address: 2620:0:862:ed1a::1
</code></pre><p>Comme attendu la réponse ne fait pas autorité quand bien même j&rsquo;ai interrogé
directement le serveur faisant autorité.
Le trafic DNS <strong>a été détourné</strong> et la réponse a été redirigé depuis un
autre serveur DNS inconnu.</p>
<p>Le détournement DNS, qu&rsquo;il soit effectué par un FAI ou par quelqu&rsquo;un d&rsquo;autre,
est hautement problèmatique.
Tout d&rsquo;abord, nous ne pouvons avoir pleinement confiance aux réponses que
nous obtenons depuis le serveur DNS.
En second, même si la réponse DNS fournit des données non falsifiées,
le trafic DNS a été détourné pour une raison inconnue, qui peut être de
la collecte et de l&rsquo;enregistrement de données, ou pour une raison
complètement différente.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Certains FAI, tels qu&rsquo;Optimum Online, Comcast, Time Warner, Cox Communications,
RCN, Rogers, Charter Communications, Verizon, Virgin Media, Frontier Communications,
Bell Sympatico, Airtel, OpenDNS et d&rsquo;autres ont commencé leurs pratiques
de détournement de DNS sur des noms de domaines inexistants (NXDOMAIN)
pour monétiser l&rsquo;affichage de publicités.
Le serveur DNS redirigait une requête pour un nom de domaine non existant
vers une fausse adresse IP qui contenait un site web avec publicités.
Je ne sais pas combien de FAI et fournisseurs de service DNS publique le
font encore.</div>

<h5 id="prévention-contre-le-détournement-de-dns">Prévention contre le détournement de DNS</h5>
<p>Si vous avez découvert que votre trafic DNS sur le port 53 est détourné,
vous avez basiquement seulement trois options afin de vous protéger :</p>
<ol>
<li>Si cela vous est possible, changez de FAI !
Votre FAI ne devrait pas détourner votre trafic DNS.</li>
<li>Paramétrez votre propre serveur DNS à distance dans un centre d&rsquo;hébergement
qui ne fait pas de détournement ou ne bloque pas le port 53.
Ensuite, que votre serveur DNS à distance écoute vos connexions DNS sur
un port non standard et rediriger toutes vos requêtes DNS vers votre
serveur DNS à distance.</li>
<li>Utilisez un VPN de confiance qui ne détourne pas le trafic DNS, ou s&rsquo;il
le fait, assurez-vous que vous pouvez faire confiance à leur politique
de non journalisation.</li>
</ol>
<h4 id="usurpation-de-dns">Usurpation de DNS</h4>
<p>L&rsquo;usurpation de DNS, aussi appelé empoisonnement du cache DNS, est différent
du détournement de DNS.
Alors que le trafic est redirigé d&rsquo;une destination vers une autre dans
une attaque de détournement de DNS, c&rsquo;est la donnée elle-même qui est
manipulée dans une attaque d&rsquo;usurpation DNS.
Souvent ces deux stratégies d&rsquo;attaques sont combinées.</p>
<p>Dans une attaque d&rsquo;usurpation de DNS, la donnée manipulée est introduite
dans le cache du résolveur DNS, résultant que le serveur de nom retourne
un résultat incorrect, e.g. une mauvaise adresse IP.</p>
<h5 id="prévention-contre-lusurpation-de-dns">Prévention contre l&rsquo;usurpation de DNS</h5>
<p>Ce type d&rsquo;attaque peut être atténuée au niveau de la couche transport ou
de la couche application en effectuant une validation de bout en bout une
fois qu&rsquo;une connexion est établie.
Un exemple courant de cela est l&rsquo;utilisation de TLS et des signatures digitales.</p>
<p><a href="https://fr.wikipedia.org/wiki/Domain_Name_System_Security_Extensions" rel="external">DNSSEC</a>
utilise des signatures digitales cryptographiques avec un certificat de clé
publique de confiance pour déterminer l&rsquo;authenticité des données.
DNSSEC peut protéger contre l&rsquo;usurpation de DNS, toutefois beaucoup
d&rsquo;administrateurs DNS ne l&rsquo;ont pas encore implémenté.</p>
<p>À partir de 2020, tous les TLD originaux prennent en charge DNSSEC, comme
le font les TLD de code de pays, mais de nombreux TLD de code de pays ne
le font toujours pas.</p>
<h2 id="appendices">Appendices</h2>
<h3 id="inspecter-dns-sur-https-doh">Inspecter DNS sur HTTPS (DOH)</h3>
<p>Je veux illustrer le fait que DoH ne fournit pas réellement une véritable
confidentialité autant de l&rsquo;adresse IP source que celle de destination,
qui peuvent être vues clairement dans la communication HTTPS.</p>
<p>En premier, je m&rsquo;assure que DoH soit désactivé dans Firefox, sur un des
ordinateurs du LAN pour adultes, et je surveille le trafic sur l&rsquo;interface
<code>em1</code> par l&rsquo;utilisation de <a href="https://man.openbsd.org/tcpdump" rel="external">tcdump</a>.
J&rsquo;ai aussi activé la journalisation dans Unbound, juste pour éviter de
remplir inutilement syslog avec trop de bruits DNS, et j&rsquo;ai utilisé
<a href="https://man.openbsd.org/tail" rel="external">tail</a> pour surveiller le journal.</p>
<p>J&rsquo;irais sur &ldquo;wikipedia.org&rdquo; dans le navigateur et voir ce que révèle la
surveillance sur le routeur.</p>
<pre tabindex="0"><code># tcpdump -n -i em1 src host 192.168.1.5 and not arp
tcpdump: listening on em1, link-type EN10MB
23:30:33.494352 192.168.1.5.55724 &gt; 192.168.1.1.53: 58136+ A? wikipedia.org.(31) (DF)
23:30:33.774439 192.168.1.5.58372 &gt; 192.168.1.1.53: 58448+ A? www.wikipedia.org.(35) (DF)
23:30:34.184287 192.168.1.5.46639 &gt; 192.168.1.1.53: 15167+ A? www.wikipedia.org.(35) (DF)
…
</code></pre><pre tabindex="0"><code># tail -f /var/unbound/log/unbound.log
Nov 05 23:30:33 unbound[12636:0] query: 192.168.1.5 wikipedia.org. A IN
Nov 05 23:30:33 unbound[12636:0] reply: 192.168.1.5 wikipedia.org. A IN NOERROR 0.097209 0 47
Nov 05 23:30:33 unbound[12636:0] query: 192.168.1.5 www.wikipedia.org. A IN
Nov 05 23:30:33 unbound[12636:0] reply: 192.168.1.5 www.wikipedia.org. A IN NOERROR 0.154989 0 80
Nov 05 23:30:34 unbound[12636:0] query: 192.168.1.5 www.wikipedia.org. A IN
Nov 05 23:30:34 unbound[12636:0] reply: 192.168.1.5 www.wikipedia.org. A IN NOERROR 0.000000 1 80
…
</code></pre><p>Naturellement nous avons vu la requête autant dans le trafic de l&rsquo;interface
que dans le journal d&rsquo;Unbound.</p>
<p>J&rsquo;ai activé alors DoH et désactivé le DNS régulier dans Firefox, en
paramétrant la valeur de <code>network.trr.mode</code> à <code>4</code>.
J&rsquo;ai alors changé les <code>paramétres réseaux</code> et paramétré Cloudflare en
tant que fournisseur DoH.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Si vous activez juste DoH via les préférences, Firefox utilisera toujours
le DNS régulier comme solution de repli.
Avant de forcer Firefox à utiliser seulement DoH, vous devez paramétrer
la value de <code>network.trr.mode</code>.</p>
<p>Écrivez <code>about:config</code> dans la barre d&rsquo;adresses et pressez la touche
<kbd>Entrée</kbd> pour accéder au panneau de configuration caché de Firefox.</p>
<p>Étape 2 : Cherchez le paramétre <code>network.trr.mode</code>.
Il contrôle la prise en charge de DoH.
Ce paramétre a 4 valeurs :</p>
<ol>
<li>DoH est désactivé, par défaut</li>
<li>DoH est actif, mais Firefox utilise à la fois DoH et le DNS régulier
selon la rapidité de la réponse retournée.</li>
<li>DoH est actif, et le DNS régulier fonctionne en repli.</li>
<li>DoH est actif, et le DNS régulier est désactivé</li>
<li>DoH est désactivé, par choix.</li>
</ol>
<p>Étape 3 : Cherchez le paramétre <code>network.trr.bootstrapAddress</code>.
Il contrôle l&rsquo;adresse IP numérique de votre serveur DoH.
Entrez la valeur <code>1.1.1.1</code> et appuyez sur la touche <kbd>Entrée</kbd>.</p>
</div>

<p>Cette fois, je visiterais &ldquo;freebsd.org&rdquo;.</p>
<pre tabindex="0"><code># tcpdump -n -i em1 src 192.168.1.5 and not arp
tcpdump: listening on em1, link-type EN10MB
00:21:10.944243 192.168.1.5.32856 &gt; 1.1.1.1.443: P 2223446146:2223446202(56) ack 157857007 win 501 (DF)
00:21:10.948719 192.168.1.5.46584 &gt; 96.47.72.84.80: S 922508523:922508523(0) win 64240 &lt;mss 1460,sackOK,timestamp 1673624773 0,nop,wscale 7&gt; (DF)
00:21:11.133801 192.168.1.5.33298 &gt; 96.47.72.84.443: S 3275123911:3275123911(0) win 64240 &lt;mss 1460,sackOK,timestamp 1673624958 0,nop,wscale 7&gt; (DF)
…
</code></pre><pre tabindex="0"><code># tail -f /var/unbound/log/unbound.log
Nov 05 23:30:33 unbound[12636:0] query: 192.168.1.5 wikipedia.org. A IN
Nov 05 23:30:33 unbound[12636:0] reply: 192.168.1.5 wikipedia.org. A IN NOERROR 0.097209 0 47
Nov 05 23:30:33 unbound[12636:0] query: 192.168.1.5 www.wikipedia.org. A IN
Nov 05 23:30:33 unbound[12636:0] reply: 192.168.1.5 www.wikipedia.org. A IN NOERROR 0.154989 0 80
Nov 05 23:30:34 unbound[12636:0] query: 192.168.1.5 www.wikipedia.org. A IN
Nov 05 23:30:34 unbound[12636:0] reply: 192.168.1.5 www.wikipedia.org. A IN NOERROR 0.000000 1 80
…
</code></pre><p>Cela révèle, depuis la surveillance de l&rsquo;interface réseau, qu&rsquo;une connexion
a été faite vers le serveur DNS de Cloudflare à l&rsquo;adresse 1.1.1.1 sur le
port 443 (HTTPS) et que nous avons visité l&rsquo;adresse IP de destination
96.47.72.84 juste après.
Dans le même temps, rien n&rsquo;est arrivé dans le journal d&rsquo;Unbound, <code>tail</code>
nous montrant juste toujours la requête précédente.</p>
<p>Si nous faisons une requête au DNS régulier sur le serveur, nous pouvons
vérifier que l&rsquo;adresse IP 96.47.72.84 est bien l&rsquo;adresse IP de &ldquo;freebsd.org&rdquo;.</p>
<p>De plus, dans cet exemple spécifique, nous pouvons même accéder au site
web de &ldquo;freebsd.org&rdquo; en écrivant juste l&rsquo;adresse IP de destination
96.47.72.84 dans le champ de la barre d&rsquo;adresse du navigateur.</p>
<p>Cela démontre que même si DoH bypasse la requête d&rsquo;un DNS régulier, il
n&rsquo;est pas capable de cacher l&rsquo;adresse IP de destination qui est toujours
présente en clair dans le trafic de la communication.</p>
<h3 id="bloquer-dns-sur-https-doh">Bloquer DNS sur HTTPS (DOH)</h3>
<p>Auparavant, le script <a href="https://codeberg.org/unixsheikh/dnsblockbuster" rel="external">DNSBlockBuster</a>
comportait certains noms de domaines DoH dans la liste, que j&rsquo;avais ajouté
aléatoirement, mais j&rsquo;ai depuis supprimé le blocage DoH du serveur DNS, car
il faut vraiment que cela soit géré au niveau du pare-feu.</p>
<p>Bloquer DoH via les noms de domaine n&rsquo;a pas beaucoup de sens à mon humble
opinion car un nom de domaine peut être cherché en premier lieu.
La plupart des clients qui utilisent DoH ont l&rsquo;adresse IP de l&rsquo;hôte du
serveur DoH encodé directement dans leur code source.</p>
<p>J&rsquo;ai cherché sur de multiples sites sur Internet, mais aucun n&rsquo;a trouvé
une simple manière de mettre à jour la liste des serveurs publiques DoH,
ainsi j&rsquo;ai décidé de faire ma propre liste appelée <a href="https://codeberg.org/unixsheikh/dohblockbuster" rel="external">DoHBlockBuster</a>.
Toutefois c&rsquo;est une tâche énorme, dont je sais que je n&rsquo;aurais pas le
temps de tenir à jour à l&rsquo;avenir, à moins que d&rsquo;autres personnnes ne s&rsquo;y
mettent ; alors si vous avez du temps libre, aidez à tenir à jour les
listes (en faisant une demande de retrait ou en m&rsquo;envoyant un courriel).
En outre, cette liste n&rsquo;est en aucun cas exhaustive.</p>
<p>Si vous n&rsquo;utilisez pas IPv6, vous pouvez bloquer tout le trafic IPv6, et
utilisez alors seulement la liste IPv4 de DoHBlockBuster.
Changez le paramétre <code>pass out</code>, dans la section &ldquo;Default protect and block&rdquo;
de <code>/etc/pf.conf</code> en <code>pass out inet</code>.
C&rsquo;est la manière pour permettre seulement le trafic IPv4 sortant, sans
avoir à bloquer spécifiquement les adresses IPv6 relatives à DoH.</p>
<p>Téléchargez les listes depuis <a href="https://codeberg.org/unixsheikh/dohblockbuster" rel="external">DoHBlockBuster</a>
et éditez les selon vos besoins et enregistrez les quelque part sur le
disque.</p>
<p>J&rsquo;ai fait un sous-répertoire à <code>/etc/pf-block-lists</code> où j&rsquo;ai placé toutes
les listes de blocage dont j&rsquo;ai besoin pour PF.</p>
<p>Créez alors un fichier persistant pour PF dans la section &ldquo;Tables&rdquo; de
<code>/etc/pf.conf</code> :</p>
<pre tabindex="0"><code># Public DoH servers.
table &lt;block_doh&gt; persist file &#34;/etc/pf-block-lists/dohblockbuster-ipv4.txt&#34;
</code></pre><p>Si vous avez besoin d&rsquo;IPv6, ajoutez alors cela aussi :</p>
<pre tabindex="0"><code>table &lt;block_doh&gt; persist file &#34;/etc/pf-block-lists/dohblockbuster-ipv4.txt&#34; file &#34;/etc/pf-block-lists/dohblockbuster-ipv6.txt&#34;
</code></pre><p>Et, alors ajoutez un <code>block</code> à la section &ldquo;Protect and block by default&rdquo;
du pare-feu :</p>
<pre tabindex="0"><code># Let&#39;s block DoH.
block in quick on { $g_lan $c_lan $dmz } to &lt;block_doh&gt;
</code></pre><p>Rechargez PF :</p>
<pre tabindex="0"><code># pfctl -f /etc/pf.conf
</code></pre><p>Vérifiez la liste avec :</p>
<pre tabindex="0"><code># pfctl -vvt block_doh -T show
</code></pre><p>Si - après quelques temps - vous voulez voir quelles adresses IP sont
actuellement bloquées, vous pouvez filtrer la sortie :</p>
<pre tabindex="0"><code># pfctl -vvt block_doh -T show | awk &#39;/\[/ {p+=$4; b+=$6} END {print p, b}&#39;
</code></pre><p>Comme mentionné précédemment, cette solution ne prend pas en considération
les serveurs DoH inconnus.
De plus afin que la liste soit efficace, elle a besoin d&rsquo;être tenue à jour.</p>
<h3 id="ajouter-loption-domain-name-à-dhcp-et-utiliser-un-fqdn">Ajouter l&rsquo;option domain-name à DHCP et utiliser un FQDN</h3>
<p>Si nous paramétrons notre réseau de telle manière que tous les ordinateurs
et dispositifs aient leurs adresses IP fixes et noms d&rsquo;hôtes, beaucoup
d&rsquo;outils ne fonctionneront pas nativement avec ces noms d&rsquo;hôtes sans ajouter
un nom de domaine au serveur DNS.
Cela est dû à des outils tel que <code>host</code> qui s&rsquo;attend à ce que la recherche
vers un nom d&rsquo;hôte soit
<a href="https://fr.wikipedia.org/wiki/Fully_qualified_domain_name" rel="external">un nom de domaine pleinement qualifié (FQDN)</a>.</p>
<p>Disons que j&rsquo;ai paramétré un ordinateur sur mon LAN ayant pour nom d&rsquo;hôte
&ldquo;foo&rdquo; et l&rsquo;adresse IP fixée à 192.168.1.7.
Je ne me souviens peut être pas que &ldquo;foo&rdquo; est l&rsquo;ordinateur avec telle
adresse, ou je ne me souviens pas quel hôte a l&rsquo;adresse IP 192.168.1.7
associée.</p>
<p>Avec un FQDN, nous pouvons faire une recherche telle que :</p>
<pre tabindex="0"><code>$ host foo.example.com
foo.example.com has address 192.168.1.7
</code></pre><p>Alors nous pouvons faire :</p>
<pre tabindex="0"><code># host 192.168.1.7
7.1.168.192.in-addr.arpa domain name pointer foo.example.com
</code></pre><p>Toutefois, il est ennuyeux de devoir écrire le nom de domaine complet à
chaque fois.
Si nous ajoutons l&rsquo;option <a href="https://man.openbsd.org/dhcp-options#option~24" rel="external">domain-name</a>
à <code>/etc/resolv.conf</code> le nom de domaine sera automatiquement ajouté.
Ainsi, nous pouvons faire juste cela :</p>
<pre tabindex="0"><code>$ host foo
foo.example.com has address 192.168.1.7
</code></pre><p>Certaines personnes recommandent d&rsquo;enregistrer un nom de domaine et de
l&rsquo;utiliser en interne sur votre LAN, et bien que ce soit certainement
fonctionnel, ce n&rsquo;est pas intéressant du tout.
Pour l&rsquo;utilisation à la maison, vous pouvez utilisez les TLD <code>.intranet</code>,
<code>.home</code> ou <code>.lan</code>, en accord avec la
<a href="https://tools.ietf.org/html/rfc6762#appendix-G" rel="external">RFC 6762</a> sans aucun
problème.
Toutefois, n&rsquo;utilisez pas <code>.local</code>.</p>
<p>Démarrons en faisant quelques changements dans la configuration de <code>/etc/dhcpd.conf</code>.
Juste pour faire simple, j&rsquo;utiliserais le serveur web de notre LAN publique
en exemple, mais vous pouvez étendre cela à tout segment où vous le désirez,
et vous pouvez aussi l&rsquo;utiliser sur plusieurs segments si besoin.</p>
<p>Dans notre paramétrage actuel, nous avons déjà le domaine <code>example.com</code>
attaché à notre serveur web ainsi nous pouvons juste l&rsquo;utiliser.
Mais si vous n&rsquo;avez pas de serveur publique qui a un réel nom de domaine,
changez-le juste par quelque chose comme <code>net.home</code>.
J&rsquo;ai changé le nom de notre serveur web par &ldquo;lilo&rdquo; (oui, de Lilo &amp; Stitch,
parce que c&rsquo;est plus cool que &ldquo;Luke&rdquo; ou &ldquo;Yoda&rdquo; !).</p>
<pre tabindex="0"><code>subnet 192.168.1.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.1.1;
    option domain-name &#34;example.com&#34;;
    option routers 192.168.1.1;
    range 192.168.1.10 192.168.1.254;
}
subnet 192.168.2.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.2.1;
    option domain-name &#34;example.com&#34;;
    option routers 192.168.2.1;
    range 192.168.2.10 192.168.2.254;
}
subnet 192.168.3.0 netmask 255.255.255.0 {
    option domain-name-servers 192.168.3.1;
    option domain-name &#34;example.com&#34;;
    option routers 192.168.3.1;
    range 192.168.3.10 192.168.3.254;
    host lilo.example.com {
        fixed-address 191.168.3.2;
        hardware ethernet 61:20:42:39:61:AF;
        option host-name &#34;lilo&#34;;
    }
}
</code></pre><p>Si vous préférez utiliser de multiples domaines plutôt qu&rsquo;un seul, dites-vous
que <code>example.com</code> est pour votre développement web professionnel, et que
<code>net.home</code> pour votre LAN privé, vous pouvez faire une <a href="https://en.wikipedia.org/wiki/Search_domain" rel="external">recherche de domaine</a>
avec l&rsquo;option <code>domain-search</code> dans <code>/etc/dhcpd.conf</code> au lieu de l&rsquo;option
<code>domain-name</code>.
La différence entre les deux est qu&rsquo;avec <code>domain-name</code>, seulement un seul
domaine est ajouté, alors qu&rsquo;avec l&rsquo;option <code>domain-search</code>, de multiples
domaines peuvent être ajoutés et sont alors &ldquo;cherchés&rdquo; un par un jusqu&rsquo;à
ce que l&rsquo;hôte soit trouvé.</p>
<p>L&rsquo;option <code>domain-search</code> ressemble à ceci :</p>
<pre tabindex="0"><code>option domain-search &#34;example.com&#34;, &#34;net.home&#34;
</code></pre><p>Alors nous avons besoin de paramétrer Unbound pour gérer nos adresses IP
fixes.
Dans cet exemple, nous avons seulement le serveur web, mais nous pouvons
utiliser autant d&rsquo;hôtes que nécessaires.
Vous pouvez juste éditer le fichier de configuration principale d&rsquo;Unbound,
mais je préfére mettre cela dans un fichier séparé et l&rsquo;inclure dans le
fichier principal.
Créez un nouveau fichier appelé tel que <code>/var/unbound/etc/unbound-local.conf</code>,
par exemple, et paramétrez vos hôtes :</p>
<pre tabindex="0"><code>local-data: &#34;lilo.example.com IN A 192.168.3.2&#34;
local-data-ptr: &#34;192.168.3.2 lilo.example.com&#34;
</code></pre><p>Ou, si vous utilisez la version <code>net.home</code> :</p>
<pre tabindex="0"><code>local-data: &#34;lilo.net.home IN A 192.168.3.2&#34;
local-data-ptr: &#34;192.168.3.2 lilo.net.home&#34;
</code></pre><p>Notez comment l&rsquo;adresse IP dans le champ <code>local-data-ptr</code> est retourné,
ce qui n&rsquo;est pas une erreur.</p>
<p>Ajoutez alors ce qui suit à notre <code>/var/unbound/etc/unbound.conf</code> :</p>
<pre tabindex="0"><code>private-address: 192.168.0.0/16
private-domain: example.com # Use net.home instead if you need that.
include: &#34;/var/unbound/etc/unbound-local.conf&#34;
</code></pre><p>Redémarrez dhcpd et Unbound :</p>
<pre tabindex="0"><code># rcctl restart dhcpd
# rcctl restart unbound
</code></pre><p>Si vous retirez le câble Ethernet de l&rsquo;un des ordinateurs connectés à l&rsquo;un
des LAN et le connectez à nouveau, vous serez notifié que <code>/etc/resolv.conf</code>
a ajouté l&rsquo;option <code>domain</code> :</p>
<pre tabindex="0"><code>domain example.com
nameserver 192.168.1.1
</code></pre><p>Vous pouvez étendre cet exemple ci-dessus à de multiples domaines et de
multiples dans tous les segments.</p>
<h3 id="ajouter-pf-badhost">Ajouter pf-badhost</h3>
<p>Lorsque vous avez paramétré votre routeur OpenBSD, je vous encourage
fortement à paramétrer <a href="https://www.geoghegan.ca/pfbadhost.html" rel="external">pf-badhost</a> !</p>
<p>pf-badhost est un script de sécurité léger fait par <a href="https://www.geoghegan.ca/about.html" rel="external">Jordan Geoghegan</a>
qui bloque les plus grandes choses irritantes d&rsquo;Internet.
Les désagréments tels les brute-forceurs SSH et SMTP sont largement éliminés
par ce script.</p>
<p>pf-badhost ajoute périodiqument des addresses IP depuis des bases de données
de spammeurs d&rsquo;IP bien connus, tel Spamhaus, Firehol, Emerging Threats
and Binary Defense, où ces mauvaises adressses IP sont fréquemment
journalisées.
pf-badhost les ajoute alors aux adresses IP collectées vers le pare-feu
PF dans une table qui est bloquée par défaut.</p>
<h3 id="lectures-recommandées">Lectures recommandées</h3>
<ul>
<li><a href="https://www.openbsd.org/faq/pf/index.html" rel="external">OpenBSD PF - User&rsquo;s Guide</a>
de la FAQ d&rsquo;OpenBSD <em>(et sa version FR : <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/pf/start" rel="external">Guide de l&rsquo;Utilisateur PF</a> officieuse)</em></li>
<li><a href="https://mwl.io/nonfiction/os#ao2e" rel="external">Absolute OpenBSD, 2nd edition</a> de
Michael Warren Lucas.
Certaines syntaxes de PF ont déjà changées depuis que Michael a écrit le
livre, mais il est toujours très utile.</li>
<li><a href="https://mwl.io/nonfiction/networking#n4sa" rel="external">Networking for System Administrators</a>
de Michael Warren Lucas.</li>
<li><a href="https://mwl.io/nonfiction/networking#n4sa" rel="external">OpenBSD and You</a></li>
<li><a href="https://blog.apnic.net/2019/11/12/stop-using-ridiculously-low-dns-ttls/" rel="external">Stop using ridiculously low DNS TTLs</a></li>
</ul>
<h3 id="comment-contribuer-à-ce-guide-">Comment contribuer à ce guide ?</h3>
<p>Veuillez considérer de contribuer si vous avez n&rsquo;importe quel commentaire,
correction, ou changement que vous considéré comme approprié.</p>
<ul>
<li>Faites un clone sur <a href="https://github.com/unixsheikh/openbsd-router-guide" rel="external">Github</a></li>
<li>Soumettez un PR pour examen</li>
</ul>
<p>Vous pouvez aussi juste envoyer un <a href="https://www.unixsheikh.com/contact.html" rel="external">courriel</a>.</p>
<h3 id="traductions-de-ce-guide">Traductions de ce guide</h3>
<p>Veuillez noter que les traductions listées ici sont commitées par d&rsquo;autres
personnes contribuant généreusement à ce guide. De fait, je ne suis pas
responsable de garder à jour ces traductions.</p>
<ul>
<li><a href="https://doc.huc.fr.eu.org/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/" rel="external">Français</a></li>
</ul>
<hr>
<p>Créé et maintenu par</p>
<p><a href="https://unixsheikh.com/" rel="external">Unix Sheikh</a></p>
<p>Le <a href="https://openbsdrouterguide.net/" rel="external">Guide du Routeur OpenBSD</a>
est sous licence <a href="https://creativecommons.org/licenses/by/4.0/" rel="external">Creative Commons Attribution 4.0 International</a>.</p>
<p>Si vous trouvez ce contenu utile, soutenez-moi sur <a href="https://patreon.com/unixsheikh" rel="external">Patreon</a>.</p>
<hr>
<h4 id="contribuer-à-la-version-fr">Contribuer à la version FR</h4>
<p>Cette version traduite du Guide du Routeur OpenBSD est faite par <a href="https://huc.fr.eu.org" rel="external">mes soins</a>.</p>
<p>Vous pouvez contribuer au-travers de mon dépôt <a href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/raw/master/content/fr/trad/unixsheikh.com/Guide-du-Routeur-OpenBSD.md" rel="external">Framagit.org</a>.</p>
<p>Par facilité, cette traduction est placée aussi sous licence <a href="https://creativecommons.org/licenses/by/4.0/" rel="external">Creative Commons Attribution 4.0 International</a>.</p>
<p>Vous pouvez soutenir mon effort de traduction en me payant un 
<a class="inside" href="/fr/don/" title="Lien interne vers l&#39;article : 'Page de dons'">bon café à l&#39;italienne comme je les &lt;3</a>
… :D</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction du &#39;Guide du Routeur OpenBSD&#39; du site unixsheikh.com]]></summary>
        <published>2020-11-23T12:00:01+01:00</published>
        <updated>2025-11-18T16:07:44+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4268a8f1-2f4c-88d7-7e3c-e9a04b10980f</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/revues/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Carnet de Revues (traductions, relectures)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Revue" scheme="http://doc.huc.fr.eu.org/fr/tags/revue/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez sur cette page mes différentes participations et autres traductions
que j&rsquo;ai faites, soit par mes propres soins, soit en collaborant avec des
équipes :</p>
<h3 id="diverses">Diverses</h3>
<p>La plupart de ces traductions diverses sont hébergés sur le wiki de la communauté &ldquo;OpenBSD pour Tous&rdquo; !</p>
<p>⇒ Date inconnue : l&rsquo;article &ldquo;<a class="inside" href="/fr/trad/comprendre-unix-en-10-minutes/" title="Lien interne vers l&#39;article : 'Comprendre Unix en 10 Minutes'">Comprendre Unix en 10 Minutes</a>&rdquo; de feu site <strong>Freeenginer.org</strong></p>
<p>⇒ <strong>2017</strong></p>
<ul>
<li>Traduction du site feu <a href="https://wiki.openbsd.fr.eu.org/doku.php/trad/libertybsd.net/start" rel="external">LibertyBSD</a></li>
</ul>
<p>⇒ <strong>2018</strong></p>
<ul>
<li>Traduction :
<ul>
<li>En Mai : &ldquo;<a class="inside" href="/fr/trad/fausses-croyances-dev-temps/" title="Lien interne vers l&#39;article : 'Fausses croyances des développeurs à-propos du temps'">Fausses croyances des développeurs à-propos du temps</a>&rdquo; et
&ldquo;<a class="inside" href="/fr/trad/fausses-croyances-dev-temps-2/" title="Lien interne vers l&#39;article : 'D&#39;autres fausses croyances des développeurs à-propos du temps'">D&#39;autres fausses croyances des développeurs à-propos du temps</a>&rdquo;</li>
<li>En Juin : de l&rsquo;article &ldquo;<a class="inside" href="/fr/trad/tumfatig.net/openbsd-collectd-influxdb-grafana/" title="Lien interne vers l&#39;article : 'Monitorer OpenBSD en utilisant CollectD, InfluxDB et Grafana'">Monitorer OpenBSD en utilisant CollectD, InfluxDB et Grafana</a>&rdquo;
du site <a href="https://www.tumfatig.net/20180220/monitoring-openbsd-using-collectd-influxdb-grafana/" rel="external">Tum&rsquo;fatig</a></li>
<li>En Septembre :
<ul>
<li>de l&rsquo;article &ldquo;<a class="inside" href="/fr/trad/tumfatig.net/telegraf-openbsd/" title="Lien interne vers l&#39;article : 'Exécuter Telegraf sur OpenBSD'">Exécuter Telegraf sur OpenBSD</a>&rdquo;
du site <a href="https://www.tumfatig.net/20180905/running-telegraf-openbsd/" rel="external">Tum&rsquo;fatig</a></li>
<li>de l&rsquo;article &ldquo;<a class="inside" href="/fr/trad/jcs.org/openbsd-surface-go/" title="Lien interne vers l&#39;article : 'OpenBSD sur la Surface Go de Microsoft'">OpenBSD sur la Surface Go de Microsoft</a>&rdquo;
du site de <a href="https://jcs.org/2018/08/31/surface_go" rel="external">Joshua Stein</a></li>
</ul>
</li>
<li>En Octobre :
<ul>
<li>de l&rsquo;article &ldquo;<a class="inside" href="/fr/trad/tumfatig.net/openbsd-raspberry-pi3/" title="Lien interne vers l&#39;article : 'Faire fonctionner OpenBSD sur le Raspberry Pi 3'">Faire fonctionner OpenBSD sur le Raspberry Pi 3</a>&rdquo;
du site <a href="https://www.tumfatig.net/20180706/running-openbsd-on-raspberry-pi-3/" rel="external">Tum&rsquo;fatig</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>⇒ <strong>2019</strong></p>
<ul>
<li>
<p>En Mars, traduction du site <strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/trad/why-openbsd.rocks/start" rel="external">Why OpenBSD Rocks !</a></strong></p>
</li>
<li>
<p>En Décembre, relecture pour le site de <strong><a href="http://poolp.org" rel="external">Gilles Chehade</a></strong>,
de deux articles - cf PR #<a href="https://github.com/poolpOrg/poolp.org/pull/30/" rel="external">30</a>
et #<a href="https://github.com/poolpOrg/poolp.org/pull/32" rel="external">32</a></p>
</li>
</ul>
<p>⇒ <strong>2020</strong></p>
<ul>
<li>
<p>En Février, différentes relectures pour le site <strong><a href="https://disroot.org" rel="external">Disroot</a></strong> - <em>pour les
remercier de m&rsquo;avoir aidé</em> - cf les PR #<a href="https://git.disroot.org/Disroot/Howto/pulls/31" rel="external">31</a> et #<a href="https://git.disroot.org/Disroot/Howto/pulls/32" rel="external">32</a></p>
</li>
<li>
<p>Traduction :</p>
<ul>
<li>En Juin : du projet <strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/trad/hambsd/start" rel="external">HamBSD.org</a></strong></li>
<li>En Août des articles de l&rsquo;excellent site <strong>BSDHowto</strong> :
<ul>
<li>&ldquo;<a class="inside" href="/fr/trad/bsdhowto.ch/externaldns/" title="Lien interne vers l&#39;article : 'Comment créer un serveur de noms avec DNS-over-TLS (DoT)'">Comment créer un serveur de noms avec DNS-over-TLS (DoT)</a>&rdquo;</li>
<li>&ldquo;<a class="inside" href="/fr/trad/bsdhowto.ch/malware/" title="Lien interne vers l&#39;article : 'Comment construire un serveur de scan de malware'">Comment construire un serveur de scan de malware</a>&rdquo;</li>
</ul>
</li>
<li>En Novembre : l&rsquo;article &ldquo;
<a class="inside" href="/fr/trad/unixsheikh.com/guide-du-routeur-openbsd/" title="Lien interne vers l&#39;article : 'Guide du Routeur OpenBSD'">Guide du Routeur OpenBSD</a>

&rdquo; du site <a href="https://unixsheikh.com/tutorials/openbsd-router-guide/" rel="external">UnixSheikh.com</a></li>
<li>En Décembre : l&rsquo;article &ldquo;
<a class="inside" href="/fr/trad/solene-rapenne/cryptpad-openbsd/" title="Lien interne vers l&#39;article : 'Héberger votre suite web office Cryptpad sous OpenBSD'">Héberger votre suite web office Cryptpad sous OpenBSD</a>

…</li>
</ul>
</li>
</ul>
<h3 id="debian">Debian</h3>
<p>⇒ <strong>2018</strong></p>
<ul>
<li>En Septembre, travail de traduction EN → FR sur les pages :
<ul>
<li>du projet <a href="https://wiki.debian.org/fr/Debian_GNU/Hurd" rel="external">GNU Hurd</a></li>
<li>du projet <a href="https://wiki.debian.org/fr/Debian_GNU/kFreeBSD" rel="external">GNU/kFreeBSD</a></li>
<li>de la <a href="https://wiki.debian.org/fr/The_Linux_Foundation" rel="external">Fondation Linux</a></li>
<li>des différentes interfaces :
<ul>
<li>des <a href="https://wiki.debian.org/fr/DesktopDefaultSettings" rel="external">paramètres par défaut de bureau</a></li>
<li>de <a href="https://wiki.debian.org/fr/FreeDesktop" rel="external">FreeDesktop</a></li>
<li>de l&rsquo;<a href="https://wiki.debian.org/fr/User_interface" rel="external">Interface Utilisateur</a></li>
<li>de l&rsquo;<a href="https://wiki.debian.org/fr/WebInterface" rel="external">Interface Web</a></li>
<li>du <a href="https://wiki.debian.org/fr/DisplayManager" rel="external">Gestionnaire d&rsquo;affichages</a>, <a href="https://wiki.debian.org/fr/Awesome" rel="external">Awesome</a>, <a href="https://wiki.debian.org/fr/MATE" rel="external">MATE</a></li>
<li>du Gestionnaire de session <a href="https://wiki.debian.org/fr/XDM" rel="external">XDM</a>, <a href="https://wiki.debian.org/fr/Xsession" rel="external">Xsession</a>, <a href="https://wiki.debian.org/fr/xinit" rel="external">xinit</a> et <a href="https://wiki.debian.org/fr/Xinitrc" rel="external">xinitrc</a></li>
<li>du serveur d&rsquo;affichage <a href="https://wiki.debian.org/fr/Wayland" rel="external">Wayland</a></li>
</ul>
</li>
<li>de la page <a href="https://wiki.debian.org/fr/home_directory" rel="external">Répertoire Personnel</a></li>
<li>et pour finir de la page <a href="https://wiki.debian.org/fr/POSIX" rel="external">POSIX</a></li>
</ul>
</li>
</ul>
<p>⇒ <strong>2019</strong></p>
<ul>
<li>
<p>Courant Mars, sur les pages :</p>
<ul>
<li>sur les <a href="https://wiki.debian.org/fr/Fonts" rel="external">Polices</a> :
<ul>
<li><a href="https://wiki.debian.org/fr/Fonts/Missing" rel="external">Polices manquantes</a></li>
<li><a href="https://wiki.debian.org/fr/Fonts/ppviewerFonts" rel="external">les polices MS Windows</a></li>
<li><a href="https://wiki.debian.org/fr/TrueType" rel="external">les polices TrueType</a></li>
</ul>
</li>
</ul>
</li>
<li>
<p>En Avril, à-propos :</p>
<ul>
<li>des Gestionnaires de fenêtres <a href="https://wiki.debian.org/fr/Dwm" rel="external">DWM</a> - <em>travail précédemment initié par un certain @thuban</em> :p - et <a href="https://wiki.debian.org/fr/i3" rel="external">i3</a></li>
<li>du fichier <a href="https://wiki.debian.org/fr/Xresources" rel="external">XResources</a></li>
</ul>
</li>
</ul>
<p>Collaborer avec cette communauté est extrêmement simple : il suffit de
s&rsquo;enregistrer et de s&rsquo;y mettre. Un régal !</p>
<h3 id="developpeznet">Developpez.net</h3>
<p>⇒ <strong>2019</strong></p>
<ul>
<li>
<p>En Mai, j&rsquo;ai fait de la relecture :</p>
<ul>
<li>du <a href="https://www.developpez.net/forums/d1958268/forums-beneficiaires-d-hebergement/priv-redaction/priv-traduction-gabarisation/traduction/2019-03-30-chapitre-6-dive-into-python-3-a/#post10947814" rel="external">chapitre 6 - Dive into Python</a> -
<em>retrouvez-la ici ⇒ 
<a class="inside" href="/fr/trad/developpez.net/dive-into-python-6-closures-et-generateurs/" title="Lien interne vers l&#39;article : 'Dive Into Python 3 - 6 : Closures et Générateurs'">Dive Into Python 3 - 6 : Closures et Générateurs</a>

</em></li>
<li>du <a href="https://www.developpez.net/forums/d1969406/forums-beneficiaires-d-hebergement/priv-redaction/priv-traduction-gabarisation/traduction/2019-05-06-dive-into-python-chapitre-8-a/#post10936823" rel="external">chapitre 8 - Dive into Python</a> -
<em>retrouvez-la ici ⇒ 
<a class="inside" href="/fr/trad/developpez.net/dive-into-python-8-iterateurs-avances/" title="Lien interne vers l&#39;article : 'Dive Into Python 3 - 8 : Itérateurs avancés'">Dive Into Python 3 - 8 : Itérateurs avancés</a>

</em></li>
<li>de <a href="https://www.developpez.net/forums/d1976102/forums-beneficiaires-d-hebergement/priv-redaction/priv-traduction-gabarisation/traduction/2017-02-25-python-3-module-of-the-week-chap-2-data-structures/" rel="external">Python 3 Module of the Week - Chap 2 : Data Structures</a> -
<em>retrouvez-la ici ⇒ 
<a class="inside" href="/fr/trad/developpez.net/pymotw3-structures-de-donnees/" title="Lien interne vers l&#39;article : 'Python 3 Module of the Week - Chap 2 : Data Structures '">Python 3 Module of the Week - Chap 2 : Data Structures </a>

</em></li>
</ul>
</li>
<li>
<p>En Juin, relecture :</p>
<ul>
<li>du <a href="https://www.developpez.net/forums/d1895623/forums-beneficiaires-d-hebergement/priv-redaction/priv-traduction-gabarisation/archives/2018-09-21-dive-into-python-3-strings/" rel="external">chapitre 4 - Dive into Python</a> -
<em>retrouvez-la en <strong><a href="/share/dive-into-python3-chapitre4-strings.odt">ODT</a></strong> et officiellement sur <strong><a href="https://python.developpez.com/tutoriels/plonger-au-coeur-de-python/?page=chapitre-4-moins-strings" rel="external">DVP</a></strong>.</em></li>
</ul>
</li>
</ul>
<p>Collaborez avec cette communauté est sympa, mais le processus est
assez lourd.</p>
<h3 id="openbsd">OpenBSD</h3>
<p>⇒ Depuis fin <strong>2016</strong>, étant co-fondateur de la communauté <strong>OpenBSD pour Tous</strong>,
principal administrateur, et traducteur :</p>
<ul>
<li>les différentes <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/start" rel="external">FAQ</a> OpenBSD :
<ul>
<li>du <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/ports/start" rel="external">Guide de Portage</a></li>
<li>du <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/pf/start" rel="external">Parefeu</a> <strong><abbr title="Packet-Filter">PF</abbr>
</strong></li>
</ul>
</li>
</ul>
<p>⇒ <strong>2017</strong> : Courant mai, commencé un gros travail de traduction sur :</p>
<ul>
<li>certaines pages du site <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/start" rel="external">OpenBSD</a></li>
</ul>
<p>⇒ <strong>2020</strong></p>
<ul>
<li>
<p>En Mai, sur les pages des projets :</p>
<ul>
<li><strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/libressl/start" rel="external">LibreSSL.org</a></strong>,</li>
<li><strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/openssh/start" rel="external">OpenSSH.com</a></strong></li>
<li><strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/openiked/start" rel="external">OpenIKED</a></strong>,</li>
<li><strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/rpki-client/start" rel="external">rpki-client</a></strong></li>
</ul>
</li>
<li>
<p>En Juin, sur les pages du site <strong><a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/openbgpd/start" rel="external">OpenBGPD.org</a></strong></p>
</li>
</ul>
<p>Je m&rsquo;efforce de maintenir principalement la traduction des pages du site
OpenBSD et de ses différentes FAQ, très régulièrement.</p>
<h3 id="python">Python</h3>
<p>Auprès de la communauté <strong>python-docs-fr</strong> :</p>
<p>⇒ <strong>2019</strong></p>
<ul>
<li>
<p>le 2 Juin, j&rsquo;ai fait remonté ma première participation #<a href="https://github.com/python/python-docs-fr/pull/805" rel="external">805</a> ;
le but étant de tester la collaboration avec l&rsquo;équipe, fusionnée le même jour !</p>
</li>
<li>
<p>le 10 Juin, j&rsquo;ai commencé mon premier travail de traduction sur la <strong>library/thread</strong>,
fusionné deux jour plus tard - PR #<a href="https://github.com/python/python-docs-fr/pull/813" rel="external">813</a>.</p>
</li>
<li>
<p>le 12 Juin, j&rsquo;ai commencé un long travail sur la <strong>library/bz2</strong> -
<em>qui pour diverses raisons, a pris environ 6 mois</em> - fusionné le 1
Février 2020 - PR #<a href="https://github.com/python/python-docs-fr/pull/818" rel="external">818</a>.</p>
</li>
<li>
<p>le 12 Juin <em>(encore)</em>, j&rsquo;ai fait une proposition de modification du fichier
<strong>README</strong>, qui a été accepté mais intégré différement - PR #<a href="https://github.com/python/python-docs-fr/pull/820" rel="external">820</a>.</p>
</li>
<li>
<p>le 29 Octobre, une proposition sur le fichier <strong>Dict</strong> qui finalement
a été repoussé - PR #<a href="https://github.com/python/python-docs-fr/pull/911" rel="external">911</a>.</p>
</li>
</ul>
<p>C&rsquo;est clairement la communauté que j&rsquo;ai le plus aimé ; collaboré avec <a href="https://github.com/Seluj78" rel="external">Seluj</a>
ou <a href="https://github.com/deronnax" rel="external">deronnax</a> est un régal.</p>
]]></content>
        <summary type="html"><![CDATA[Carnet de revues concernant les différentes traductions EN → FR que j&#39;ai faites et autres relectures auquelles j&#39;ai participées]]></summary>
        <published>2020-11-21T10:52:01+01:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:907b47bc-5030-d044-a3c5-36dfe9a16931</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/add-apt-key/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Apt : Ajouter une clé GPG</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Devuan" scheme="http://doc.huc.fr.eu.org/fr/tags/devuan/" />
        <category term="apt" scheme="http://doc.huc.fr.eu.org/fr/tags/apt/" />
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Historiquement, pour ajouter une clé GPG pour l&rsquo;outil <strong>apt</strong>, on utilisait
la commande <code>apt-key</code>. Or, cette commande est déclarée obsolète !</p>
<p>Quand vous utilisez la commande, vous avez le droit à ce message d&rsquo;erreur : <br>
<code>Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).</code></p>
<p>Il est maintenant recommandé de déposer la clé dans le répertoire
<code>/etc/apt/keyrings/</code> !</p>
<h2 id="code">Code</h2>
<p>Pour me simplifier la vie, je me suis créé ce petit script <code>add-apt-k.sh</code>,
que je symlink vers mon répertoire personnel <code>~/bin/</code> - <em>ainsi je peux
l&rsquo;appeler où que je sois dans la racine du système</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">dir_keys</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/etc/apt/keyrings/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">url</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>read -p <span style="color:#48b685">&#34;Quel est le nom du projet ? &#34;</span> name
</span></span><span style="display:flex;"><span>read -p <span style="color:#48b685">&#34;Où est l&#39;URL de la clé GPG (à ajouter pour l&#39;outil apt) ? &#34;</span> url
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># creation du repertoire local de clés</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> ! -d <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_keyrs</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> mkdir -p <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_keys</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># recupération de la clé du projet</span>
</span></span><span style="display:flex;"><span>curl -fsSL <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">url</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | gpg --dearmor | tee <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_keys</span><span style="color:#f99b15">}</span><span style="color:#48b685">/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">.gpg&#34;</span> &gt; /dev/null
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">status</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$?</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">status</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -eq <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s : %s\n&#39;</span> <span style="color:#48b685">&#34;OK&#34;</span> <span style="color:#48b685">&#34;La clé GPG pour le projet &#39;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#39; a bien été ajoutée.&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#39;%s : %s\n&#39;</span> <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Il semble y avoir un soucis pour ajouter la clé GPG du projet &#39;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#39; !&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><p>Ensuite :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ chmod <span style="color:#f99b15">0700</span> <span style="color:#ef6155">$HOME</span>/repertoire/add-apt-key.sh
</span></span><span style="display:flex;"><span>$ ln <span style="color:#ef6155">$HOME</span>/repertoire/add-apt-key.sh <span style="color:#ef6155">$HOME</span>/bin
</span></span></code></pre></div><p>Puis appel du script : <code>$ sudo ~/bin/add-apt-key.sh</code></p>
<hr>
<p>Ensuite utilisation de l&rsquo;outil apt pour éditer les sources et mise à jour
de la base de données d&rsquo;apt puis installation du binaire.</p>
<hr>
<p>Plus d&rsquo;informations sur le forum Debian-fr.org : <a href="https://www.debian-fr.org/t/apt-ajout-correct-dune-cle-gpg/85278" rel="external">https://www.debian-fr.org/t/apt-ajout-correct-dune-cle-gpg/85278</a></p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Debian, Devuan : Ajouter correctement une clé GPG pour l&#39;outil apt et résoudre l&#39;erreur &#39;Warning: apt-key is deprecated&#39;.]]></summary>
        <published>2020-11-20T15:13:19+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1ca91ab1-ad49-5ad8-45bf-d1512633e7e1</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-bluetooth/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD et le Bluetooth</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Bluetooth" scheme="http://doc.huc.fr.eu.org/fr/tags/bluetooth/" />
        <category term="Audio" scheme="http://doc.huc.fr.eu.org/fr/tags/audio/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>OpenBSD et quoi ?!</p>
<p>Soyons sérieux !</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>En fait, depuis <a href="https:*marc.info/?l=openbsd-cvs&amp;m=140511572108715&amp;w=2" rel="external">2014</a>,
la pile Bluetooth a été supprimé d&rsquo;OpenBSD ; écriture du code &ldquo;moyen-âge&rdquo;,
pas assez sécurisé et personne ne veut s&rsquo;y mettre !</p>
<ul>
<li>alors, <em>si vous avez les compétences de développeurs, et que vous avez
de solides connaissances sur le protocole Bluetooth et que vous acceptez
de collaborer avec l&rsquo;équipe OpenBSD</em> : <strong>contactez-les</strong> !</li>
</ul></div>

<h2 id="bluetooth-audio">Bluetooth Audio</h2>
<p>Oui, mais…</p>
<p>Officieusement, cela fonctionne grâce à un dongle USB Récepteur Audio
Bluetooth, tel les <strong>Creative BT-W2, BT-W3</strong> ou le <strong>Jabra Evolve 2 85</strong> !</p>
<p>Vous l&rsquo;avez ? Connectez-le tout simplement !</p>
<p>Astuce : Au cas où… vérifiez dans le Bios, que le paramétrage du mode
USB 3, soit bien actif, et non pas en mode auto ou désactivé !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>uaudio0 at uhub0 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Creative Labs Creative Bluetooth Audio W2&#34;</span> 
</span></span><span style="display:flex;"><span>    rev 2.00/1.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uaudio0: class v1, full-speed, sync, channels: <span style="color:#f99b15">2</span> play, <span style="color:#f99b15">1</span> rec, <span style="color:#f99b15">0</span> ctls
</span></span><span style="display:flex;"><span>audio1 at uaudio0
</span></span><span style="display:flex;"><span>uhidev0 at uhub0 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">3</span> <span style="color:#48b685">&#34;Creative Labs Creative Bluetooth Audio W2&#34;</span>
</span></span><span style="display:flex;"><span>    rev 2.00/1.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uhidev0: iclass 3/0, <span style="color:#f99b15">3</span> report ids
</span></span><span style="display:flex;"><span>uhid0 at uhidev0 reportid 1: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>2, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhid1 at uhidev0 reportid 2: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>18, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>18, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhid2 at uhidev0 reportid 3: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>64, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>64, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span></code></pre></div><p>Vous avez ce genre de messages, la led bleue clignote : c&rsquo;est OK !</p>
<h3 id="appairage-bt">Appairage BT</h3>
<p>Pressez le bouton du récepteur audio Bluetooth, la led bleu va clignoter
très rapidement. Il reste plus qu&rsquo;à activer l’appairage de votre
périphérique audio.</p>
<h3 id="gestion-du-service-audio">Gestion du service audio</h3>
<p>Attachez votre dongle USB au serveur audio <code>sndiod</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl set sndiod flags &#34;-f rsnd/0 -F rsnd/1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl restart sndiod</span>
</span></span></code></pre></div><h4 id="openbsd--68">OpenBSD ≥ 6.8</h4>
<p>L&rsquo;outil natif <code>sndioctl</code> permet de contrôler le volume, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ sndioctl output.level<span style="color:#5bc4bf">=</span>+0.05
</span></span><span style="display:flex;"><span>$ sndioctl output.level<span style="color:#5bc4bf">=</span>-0.05
</span></span></code></pre></div><h4 id="openbsd--67">OpenBSD ≤ 6.7</h4>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>aucatctl</code> et utilisez-le en mode console, tel que :</p>
<p><code>$ aucatctl master=20</code></p>
<h2 id="remerciement">Remerciement</h2>
<ul>
<li>un premier @jcs</li>
<li>un second à Matthias Schmidt ; cf : <a href="https://xosc.org/bluetooth.html" rel="external">https://xosc.org/bluetooth.html</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour gérer le Bluetooth sur OpenBSD]]></summary>
        <published>2020-11-03T16:28:42+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4a00cb8b-65eb-29c5-df96-83cc12d361f4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/openssh/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : OpenSSH pour remplacer Dropbear</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="OpenSSH" scheme="http://doc.huc.fr.eu.org/fr/tags/openssh/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par défaut, OpenWRT est livré avec Dropbear. Bien que ce serveur 
























































































<span lang="en">SSH <em>(Secure SHell)</em></span>























utilise seulement la version 2 du protocole 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















, et soit léger,
il comporte quelques lacunes :</p>
<ul>
<li>Il a un support partial du protocole 


















































































<span lang="en">SFTP <em>(SSH File Transfer Protocol)</em></span>




























 ; il faut lui
adjoindre le     paquet <strong>openssh-sftp-server</strong> pour que ce soit fonctionnel.</li>
<li>Il n&rsquo;a aucune séparation de privilège utilisateur.</li>
<li>Il n&rsquo;a pas officiellement de support des modules cryptographiques, approuvés
par la <strong>FIPS 140-2</strong>. <em>(bien que dans notre contexte particulier,
ce ne soit pas une nécessité)</em></li>
<li>Depuis, la version <strong>2020.79</strong>, Dropbear semble gérer l&rsquo;utilisation des
algorythmes à courbes Elliptiques - <em>ce qui n&rsquo;est pas le cas des versions
précédentes, incluses avant 19.07.4</em> - tel que :
<ul>
<li>hostkey <strong>ed25519</strong></li>
<li>le chiffrement <strong>chacha20-poly1305</strong></li>
<li>voire les signatures de clés au format <strong>rsa-sha2</strong></li>
</ul>
</li>
</ul>
<h2 id="installation">Installation</h2>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# opkg update
:# opkg install openssh-server openssh-moduli
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Le paquet <strong>openssh-moduli</strong> n&rsquo;est pas strictement nécessaire. Pour rappel,
le fichier <code>/etc/ssh/moduli</code> est un fichier contenant les nombres premiers
et les générateurs à utiliser par le serveur SSH dans la méthode d&rsquo;échange
des clés de groupe</p>
<p><span lang="en">DH <em>(Diffie-Hellman)</em></span></p>
<p>. Préférez l&rsquo;installer…</p>
</div>

<h2 id="configuration">Configuration</h2>
<h3 id="dropbear">Dropbear</h3>
<p>Mieux vaut laisser Dropbear sur le port par défaut.</p>
<p>Néanmoins, vous pouvez le reconfigurer soit par l&rsquo;interface LuCI, soit
en mode console - <em>ce qui peut se faire ainsi</em> :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# uci set dropbear.@dropbear[0].Port=xxx
:# uci commit dropbear
:# /etc/init.d/dropbear restart
</code></pre><p>où <code>xxx</code> est le numéro de port que vous choisirez !</p>
<p>puis connectez-vous au serveur sur ce nouveau numéro de port.</p>
<h3 id="openssh">OpenSSH</h3>
<ul>
<li>Fichier de configuration : <code>/etc/ssh/sshd_config</code></li>
</ul>
<hr>
<p>Les recommandations de bases suivantes s&rsquo;appliquent ABSOLUMENT :</p>
<ul>
<li>n&rsquo;utiliser <strong>QUE la Version 2</strong> du protocole,</li>
<li>NE <strong>PAS</strong> permettre au compte <strong>root</strong> de se connecter,</li>
<li><strong>désactiver l&rsquo;authentification par mot de passe</strong>,</li>
<li>n&rsquo;utiliser <strong>QUE l&rsquo;authentification par clés</strong>.</li>
</ul>
<hr>
<p>Nous allons en profitez pour durcir la configuration par défaut :</p>
<ul>
<li><a class="inside" href="/fr/sec/ssh/sshd-durci/#recr%c3%a9ation-des-cl%c3%a9s-dh%c3%b4te" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">recréons les clés d'hôtes</a>
 proprement.
Et tant qu&rsquo;à faire, autorisons QUE les clés au format <strong>Ed25519</strong>. <br>
<em><a class="inside" href="/fr/sec/ssh/configuration-securisee/" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">Lisez mon autre article</a>
,
pour savoir comment créer de manière correcte des clés au format ed25519.</em></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">À savoir qu&rsquo;au démarrage du serveur OpenSSH, il recréera les clés <strong>ECDSA</strong>.</div>

<ul>
<li>autorisons QUE :
<ul>
<li>les <a class="inside" href="/fr/sec/ssh/sshd-durci/#chiffrements" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">chiffrements</a>
 forts,</li>
<li>les algorithmes  suivants :
<ul>
<li>d&rsquo;<a class="inside" href="/fr/sec/ssh/sshd-durci/#%c3%a9change-de-cl%c3%a9s" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">échange de clés</a>
,</li>
<li>de <a class="inside" href="/fr/sec/ssh/sshd-durci/#algorithmes-de-cl%c3%a9-h%c3%b4te" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">clés d'hôtes</a>
</li>
<li>des <a class="inside" href="/fr/sec/ssh/sshd-durci/#message-authentication-codes" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">codes d'authentification de messages</a>
,</li>
</ul>
</li>
</ul>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Les algorithmes des clés d&rsquo;hôtes <strong><a href="mailto:sk-ssh-ed25519@openssh.com" rel="external">sk-ssh-ed25519@openssh.com</a>,sk-ssh-ed25519-cert-v01@openssh.com</strong>
ne semblent pas être reconnus ; <strong>NE les ajoutez PAS !</strong></div>

<p><strong>Pour finir, ne configurez pas le service sur le port 22 ; en cas de problème,
Dropbear pourra toujours vous être utile, même s&rsquo;il faut le réactiver !</strong></p>
<h4 id="fichier-moduli">Fichier moduli</h4>
<p>Si vous avez installé le paquet <strong>openssh-moduli</strong>, il serait préférable
de n&rsquo;accepter que les échanges de clés de groupe <abbr title="Diffie-Hellman">DH</abbr>

supérieure ou égale à 3072 bits.</p>
<p>Avant de le modifier, sauvegardons le fichier, au cas où…</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# cp /etc/ssh/moduli /etc/ssh/moduli.bckp
:# chmod 0400 /etc/ssh/moduli.bckp
</code></pre><p>Ensuite, il faut le <a class="inside" href="/fr/sec/ssh/sshd-durci/#moduli--linux" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">recréer</a>
</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Si vous avez configuré correctement un utilisateur ayant des droits <a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">sudo</a>
:</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# sudo awk &#39;$5 &gt;= 3071&#39; /etc/ssh/moduli | sudo tee /etc/ssh/moduli.safe
:# mv /etc/ssh/moduli.safe /etc/ssh/moduli
</code></pre></div>

<h4 id="tldr">TL;DR</h4>
<p>Voici un exemple minimaliste du fichier de configuration du serveur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_rsa_key</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_ed25519_key</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PermitRootLogin no</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">MaxAuthTries 3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PubkeyAuthentication yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AuthorizedKeysFile  .ssh/authorized_keys</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PasswordAuthentication no</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PermitEmptyPasswords no</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Subsystem   sftp    /usr/lib/sftp-server</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Vous avez paramétré l&rsquo;option <strong>ListenAddress</strong> ? Oubliez ou vous buterez
face à une <a href="/fr/sys/openwrt/openssh/#situation-de-compétition">situation de compétition</a> !</div>

<hr>
<h2 id="gestion-des-services">Gestion des services</h2>
<h3 id="service-openssh">Service OpenSSH</h3>
<p>Et, voilà, maintenant, il ne vous reste plus qu&rsquo;à vous connecter… après
avoir testé la configuration puis activé et démarré le service :</p>
<p><code>:# sshd -t</code></p>
<p>Si la configuration est valide :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# /etc/init.d/sshd enable
:# /etc/init.d/sshd start
</code></pre><h3 id="service-dropbear">Service Dropbear</h3>
<p>Vous pouvez vous connecter au service d&rsquo;OpenSSH, sans soucis ? <br>
Maintenant, vous pouvez arrêter et désactiver le service :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">:# /etc/init.d/dropbear stop
:# /etc/init.d/dropbear disable
</code></pre><hr>
<h2 id="sauvegarde-système">Sauvegarde système</h2>
<p>Normalement, le répertoire <code>/etc/ssh</code> et ce qu&rsquo;il contient est inclus
dans la sauvegarde système par l&rsquo;outil <code>sysupgrade</code>.</p>
<p>Pour le vérifier : <code>:# sysupgrade -l | grep ssh</code></p>
<p>Si ce n&rsquo;est pas le cas, éditez le fichier <code>/etc/sysupgrade.conf</code> et ajoutez
le répertoire.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="situation-de-compétition">Situation de compétition</h3>
<p>⇒ Impossible de se connecter après un redémarrage :</p>
<p>Avez-vous paramétré l&rsquo;option <code>ListenAdress</code> dans le fichier de configuration
du service ?</p>
<p>Si oui, <span class="red">désactivez la ligne correspondante </span>
.
Du fait d&rsquo;une <strong>situation de compétition</strong>, le démarrage du service OpenSSH ne
peut pas s&rsquo;effectuer.</p>
<p>Si vous spécifiez l&rsquo;option <strong>ListenAddress</strong>, OpenSSH s&rsquo;exécutera lorsque
vous le démarrerez. Néanmoins, au redémarrage de la machine, OpenSSH
échouera à démarrer car il ne trouvera pas les interfaces réseau !</p>
<p>Donc, évitez de spécifier cette option et configurez le parefeu pour
n&rsquo;autoriser que sur l&rsquo;interface de votre LAN.</p>
<p><em><a href="https://forum.openwrt.org/t/luci-https-not-working-after-upgrade-to-19-7-4/74352/16" rel="external">source</a></em></p>
<h2 id="documentation">Documentation</h2>
<h3 id="wikipédia">Wikipédia</h3>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Comparison_of_SSH_servers" title="Article Wikipédia : Comparison_of_SSH_servers">Comparison_of_SSH_servers <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
, <a href="https://en.wikipedia.org/wiki/FIPS_140-2" title="Article Wikipédia : FIPS_140-2">FIPS_140-2 <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://fr.wikipedia.org/wiki/Situation_de_comp%c3%a9tition" title="Article Wikipédia : Situation_de_compétition">Situation_de_compétition <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer OpenSSH dans OpenWRT pour remplacer Dropbear.]]></summary>
        <published>2020-09-20T12:02:05+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:bb7d5630-becc-b64a-4693-235336d2661b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/sshd-durci/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenSSH : Durcir la configuration du serveur SSH</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par défaut, même sous OpenBSD, la configuration de SSH n&rsquo;est pas des
plus sécurisées.</p>
<p>Les algorithmes NISTP, voire du SHA1, sont encore utilisés.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il est impératif QUE la version du serveur OpenSSH utilisée soit supérieure
à la version 6.5 !</div>

<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration : <code>/etc/ssh/sshd_config</code></li>
</ul>
<hr>
<p>Bien sûr, hormis le fait de :</p>
<ul>
<li>n&rsquo;utiliser <strong>QUE la Version 2</strong> du protocole,</li>
<li>NE <strong>PAS</strong> permettre au compte <strong>root</strong> de se connecter,</li>
<li><strong>désactiver l&rsquo;authentification par mot de passe</strong>,</li>
<li>n&rsquo;utiliser <strong>QUE l&rsquo;authentification par clés</strong>.</li>
</ul>
<h3 id="recréation-des-clés-dhôte">Recréation des clés d&rsquo;Hôte</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cd /etc/ssh
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rm ssh_host_*</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N &#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N &#34;&#34; -o -a 64</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Ne mettez pas de passphrases lors de la génération, autrement le serveur ne
sera pas capable de les lire…</p>
<p>De toute facon, le fichier <code>/var/log/auth</code> vous le dira !</p>
</div>

<hr>
<p>Ensuite, il faut veillez aux choses ci-dessous :</p>
<h3 id="hostkey">HostKey</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><span class="red">NE PAS utiliser les protocoles de chiffrement DSA, ECDSA</span></div>

<p><strong>Commentez</strong> les déclarations <code>HostKey</code> pour <span em>ne garder que celles
relatives au chiffrement RSA et ED25519</span>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_rsa_key</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_ed25519_key</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Vous pouvez très bien n&rsquo;utiliser que les clés à courbe elliptiques, de type
ed25519. Dans ce cas-là, veillez à ce que tous vos clients puissent utiliser
aussi ce mode de chiffrement.</div>

<h3 id="chiffrements">Chiffrements</h3>
<p>Les <strong>chiffrements</strong> à autoriser sont :</p>
<p><code>Ciphers chacha20-poly1305@openssh.com</code></p>
<h3 id="échange-de-clés">Échange de clés</h3>
<p>Les <strong>algorithmes d&rsquo;échanges de clé</strong> à privilégier sont :</p>
<p><code>KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com</code></p>
<h3 id="algorithmes-de-clé-hôte">Algorithmes de clé Hôte</h3>
<p>Les <strong>algorithmes de clé d&rsquo;Hôte</strong> sont :</p>
<p><code>HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il est possible que selon la version de votre serveur, cette définition
d&rsquo;algorithme provoque une erreur. Veuillez lire la section
<a href="/fr/sec/ssh/sshd-durci/#bad-key-types">Dépannage</a> !</div>

<h3 id="message-authentication-codes">Message Authentication Codes</h3>
<p>Les algorithmes des <strong>Codes d&rsquo;Authentification de Messages</strong> sont :</p>
<p><code>MACs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com</code></p>
<h3 id="le-fichier-moduli">Le fichier Moduli</h3>
<p>Le fichier moduli est un fichier contenant les nombres premiers et les
générateurs à utiliser par le serveur SSH dans la méthode d&rsquo;échange
des clés de groupe 











<span lang="en">DH <em>(Diffie-Hellman)</em></span>



































































































.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Depuis 2017, le <a href="https://bugzilla.mindrot.org/show_bug.cgi?id=2793" rel="external">bogue #2793</a>
explique que dans certains contextes le bon fonctionnement échoue, suite
aux recommandations ci-dessous.</p>
<p>Si vous n&rsquo;arrivez plus à vous connecter, envisagez de revenir en arrière
sur cette modification !</p>
</div>

<h4 id="moduli--linux">Moduli / Linux</h4>
<p>Il est recommandé de le recréer de telle manière :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>awk <span style="color:#48b685">&#39;$5 &gt;= 3071&#39;</span> /etc/ssh/moduli &gt; /etc/ssh/moduli.safe
</span></span><span style="display:flex;"><span>mv /etc/ssh/moduli.safe /etc/ssh/moduli
</span></span></code></pre></div><h4 id="moduli--openbsd">Moduli / OpenBSD</h4>
<p>S&rsquo;il est possible de le créer ainsi : <br>
<code>ssh-keygen -G /etc/ssh/moduli -b 3072</code></p>
<p>attention, la génération sera longue et dépend très fortement de la puissance
machine de votre serveur.</p>
<p>Néanmoins, sachez que depuis quelques années/versions, le fichier est déjà
généré et se trouve être : <code>/etc/moduli</code></p>
<p>Pour en savoir plus, lisez le manpage 
<a class="man" href="https://man.openbsd.org/moduli.5" title="Page du Manuel OpenBSD pour : moduli">moduli(5)</a>
</p>
<h3 id="sandbox">Sandbox</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Cette option est <span em>obsolète depuis la version 7.5</span>.</p>
<p>Veillez à ne plus l&rsquo;utiliser !</p>
</div>

<h2 id="tldr">TL;DR</h2>
<p>Voici un exemple minimaliste du fichier de configuration sécurisée côté
serveur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Port 22</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ListenAddress 192.168.xxx.yyy</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ListenAddress fd00:abcd:efg0::1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_rsa_key</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKey /etc/ssh/ssh_host_ed25519_key</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Ciphers chacha20-poly1305@openssh.com</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">MACs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PermitRootLogin no</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PubkeyAuthentication yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AuthorizedKeysFile  .ssh/authorized_keys</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PasswordAuthentication no</span>
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<h3 id="bad-key-types">Bad key types</h3>
<p>Si vous avez l&rsquo;erreur suivante : <br>
<code>/etc/ssh/sshd_config line 26: Bad key types 'ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com'</code></p>
<p>Enlevez les deux déclarations suivantes
<code>sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com</code>
et <a href="/fr/sec/ssh/sshd-durci/#test">testez</a> à nouveau, puis si c&rsquo;est <strong>OK</strong>, relancez le service.</p>
<h3 id="logingracetime">LoginGraceTime</h3>
<p>Du fait de générer des clés RSA + PKBDF, ou ed25519, si vous avez paramétré
l&rsquo;option <code>LoginGraceTime</code>, pour la diminuer au strict minimum, pensez à
<strong>augmenter sa valeur, sinon</strong> vous aurez <strong>le droit à ne pas pouvoir vous
connecter, sans aucun message d&rsquo;erreur</strong> dans le log d&rsquo;authentification.</p>
<hr>
<h3 id="test">Test</h3>
<ul>
<li>Vérifier la configuration : <code>:# sshd -t</code></li>
</ul>
<hr>
<h4 id="ssh-audit">ssh-audit</h4>
<p>Pour tester la configuration de votre serveur, il existe un outil nommé
<code>ssh-audit</code>. Installez-le et exécutez à l&rsquo;encontre de votre serveur SSH :</p>
<p><code>:$ ssh-audit adresse-ip-serveur-ssh</code></p>
<ul>
<li>Tout message en rouge est à corriger URGEMMENT.</li>
<li>Tout message en vert signifie que l&rsquo;analyse en question est bonne.</li>
</ul>
<h4 id="sshaudit-internet">sshaudit internet</h4>
<p>Il est possible de tester la valeur de la configuration de votre serveur
sur le site <strong>sshaudit</strong> : <a href="https://www.sshaudit.com" rel="external">https://www.sshaudit.com</a></p>
<hr>
<h2 id="documentation">Documentation</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/sshd.8" title="Page du Manuel OpenBSD pour : sshd">sshd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/sshd_config.5" title="Page du Manuel OpenBSD pour : sshd_config">sshd_config(5)</a>
, 
<a class="man" href="https://man.openbsd.org/sftp-server.8" title="Page du Manuel OpenBSD pour : sftp-server">sftp-server(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/moduli.5" title="Page du Manuel OpenBSD pour : moduli">moduli(5)</a>
</li>
</ul>
<h3 id="autres">Autres</h3>
<ul>
<li><a href="https://infosec.mozilla.org/guidelines/openssh" rel="external">https://infosec.mozilla.org/guidelines/openssh</a></li>
<li><a href="https://www.sshaudit.com/hardening_guides.html" rel="external">https://www.sshaudit.com/hardening_guides.html</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Configurer le serveur SSH pour une configuration plus sécurisée, que celle par défaut.]]></summary>
        <published>2020-09-18T15:58:58+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:45fd50cd-b1c8-3046-4dbc-ec10e3cf6ef3</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-compose/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion de la touche de composition sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="unicode" scheme="http://doc.huc.fr.eu.org/fr/tags/unicode/" />
        <category term="compose" scheme="http://doc.huc.fr.eu.org/fr/tags/compose/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La touche <code>Compose</code>, dite touche de composition est une touche suivi
d&rsquo;un ensemble d&rsquo;une ou plusieurs touches qui permet d&rsquo;imprimer les
caractères <a class="inside" href="/fr/sys/openbsd/tip-unicode/" title="Lien interne vers l&#39;article : 'Gestion de l&#39;Unicode sous OpenBSD'">Unicode</a>
 de
manière pratique.</p>
<p>Il faut &ldquo;voir&rdquo; la touche de composition comme un raccourci à la
combinaison des touches.</p>
<p>Sous X, souvent le DE permet de définir une touche Compose. Une fois que
vous avez fait vos modifications systèmes, il est nécessaire de
redémarrer votre session !</p>
<h2 id="configuration">Configuration</h2>
<p>Il existe plusieurs moyens de configurer la touche de composition :</p>
<ul>
<li>
<p>selon votre bureau graphique, tel <a href="/fr/sys/openbsd/tip-compose/#gnome">Gnome</a>, <a href="/fr/sys/openbsd/tip-compose/#kde">KDE</a>, <a href="/fr/sys/openbsd/tip-compose/#xfce">Xfce</a>…</p>
</li>
<li>
<p>la configuration des fichiers <a href="/fr/sys/openbsd/tip-compose/#fichier-xcompose">.XCompose</a>,
<a href="/fr/sys/openbsd/tip-compose/#fichier-xmodmap">.Xmodmap</a> et <a href="/fr/sys/openbsd/tip-compose/#fichier-xsession">.xsession</a> n&rsquo;est utile
que pour les sessions terminales, en mode console, voire les environnements
graphiques différents des bureaux graphiques.</p>
</li>
</ul>
<h3 id="gnome">Gnome</h3>
<p>Menu &ldquo;Préférences&rdquo; &gt; option &ldquo;Position de la touche compose&rdquo;</p>
<h3 id="kde">KDE</h3>
<p>Menu &ldquo;Paramètres&rdquo; (Alt+F2) &gt; &ldquo;Régions et langues&rdquo;, puis choisir l&rsquo;option
&ldquo;Avancé&rdquo; dans &ldquo;Disposition du clavier&rdquo;. Puis parmi les options Xkb,
cherchez &ldquo;position de la touche compose&rdquo;.</p>
<h3 id="xfce">Xfce</h3>
<h4 id="xfce--414">Xfce ≥ 4.14</h4>
<p>Depuis Xfce 4.14, le sélecteur est renommé : &ldquo;Touche de composition&rdquo;.</p>
<h4 id="xfce--414-1">Xfce &lt; 4.14</h4>
<p>C&rsquo;est dans &ldquo;Paramètres&rdquo; &gt; &ldquo;Clavier&rdquo; : onglet &ldquo;Disposition&rdquo;, puis définir
le sélecteur &ldquo;Touche composée&rdquo;.</p>
<h3 id="fichier-xcompose">Fichier .XCompose</h3>
<p>Le fichier <code>~/.XCompose</code> sert à définir vos combinaisons de touche
personnalisées.</p>
<p>Pour exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">&lt;Multi_key&gt; &lt;at&gt; &lt;v&gt;    :   &#34;✓&#34; U2713   # CHECK MARK</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">&lt;Multi_key&gt; &lt;at&gt; &lt;at&gt; &lt;v&gt;   :   &#34;✔&#34; U2714   # HEAVY CHECK MARK</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">&lt;Multi_key&gt; &lt;at&gt; &lt;X&gt;        :   &#34;✗&#34; U2717   # BALLOT X</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">&lt;Multi_key&gt; &lt;at&gt; &lt;at&gt; &lt;X&gt; : &#34;✘&#34; U2718 # HEAVY BALLOT X</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">&lt;Multi_key&gt; &lt;Multi_key&gt; &lt;t&gt; &lt;e&gt; &lt;l&gt; : &#34;☎&#34; U260E # BLACK TELEPHONE</span>
</span></span></code></pre></div><p>Dans cet exemple, la touche <code>&lt;Multi_key&gt;</code> est votre touche de
composition ; la touche <code>&lt;at&gt;</code> correspond à la touche <kbd>@</kbd> et
les autres correspondent à vos lettres que vous retrouvez sur votre
clavier.</p>
<h3 id="fichier-xmodmap">Fichier .Xmodmap</h3>
<p>Pour la gestion de cette fonction, en mode terminal ou dans une console,
il faut créer le fichier <code>~/.Xmodmap</code> et définir dedans :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># key Compose : Touche Window</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">keycode 115</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">Multi_key</span>
</span></span></code></pre></div><h3 id="fichier-xsession">Fichier .xsession</h3>
<p>Ajouter à votre fichier <code>~/.xsession</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Gestion des touches clavier</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmodmap $HOME/.Xmodmap</span>
</span></span></code></pre></div><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Aide:Caract%C3%A8res_sp%C3%A9ciaux_probl%C3%A9matiques" rel="external">https://fr.wikipedia.org/wiki/Aide:Caract%C3%A8res_sp%C3%A9ciaux_probl%C3%A9matiques</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Touche_compose" rel="external">https://fr.wikipedia.org/wiki/Touche_compose</a></li>
<li>Le manpage : <a href="http://man.openbsd.org/XCompose" rel="external">http://man.openbsd.org/XCompose</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour gérer la composition sous OpenBSD]]></summary>
        <published>2020-09-18T12:24:39+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:6dcb70a6-49a7-1d00-3c4e-5d7b79d8054e</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/que-se-passe-t-il-quand-vous-ecrivez-dans-la-barre-d-adresse-du-navigateur-web/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Que se passe-t-il quand vous écrivez dans la barre d&#39;adresse du navigateur web…</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <content type="html"><![CDATA[<h2 id="prologue">Prologue</h2>
<p>Cet article est la traduction de l&rsquo;article anglais <strong>&quot;<a href="https://github.com/alex/what-happens-when" rel="external">What happens when…</a>&quot;</strong>
d&rsquo;Alex Gaynor. De même que l&rsquo;article original est sous <a href="https://creativecommons.org/publicdomain/zero/1.0/deed.fr" rel="external">licence CC0</a>, ainsi
est la traduction de cet article.</p>
<hr>
<h2 id="que-se-passe-t-il-quand">Que se passe-t-il quand…</h2>
<p>Ce dépôt est une tentative pour répondre à cette vieille question d&rsquo;interview
&ldquo;Que se passe-t-il quand vous écrivez google.com dans la barre d&rsquo;adresse
de votre navigateur web et que vous appuyez sur la touche Entrée ?&rdquo;</p>
<p>Hormis l&rsquo;habituel histoire, nous allons essayer de répondre à cette question
avec autant de détails que possible. Rien ne sera négligé.</p>
<p>Ceci est un processus collaboratif, alors svp creusez et essayez d&rsquo;aider !
Il y a des tonnes de détails manquants qui n&rsquo;attendent que vous pour les
ajouter ! SVP, envoyez-nous vos requêtes !</p>
<p>Tout ceci est sous les termes de la licence <a href="https://creativecommons.org/publicdomain/zero/1.0/deed.fr" rel="external">Creative Commons Zero</a></p>
<p>Vous pouvez lire ceci en <a href="https://github.com/skyline75489/what-happens-when-zh_CN" rel="external">简体中文</a> (Chinois simplifié), <a href="https://github.com/tettttsuo/what-happens-when-JA" rel="external">日本語</a> (Japonais)
et <a href="https://github.com/SantonyChoi/what-happens-when-KR" rel="external">한국어</a> (Coréen).  NOTE : ces traductions n&rsquo;ont pas été examinées par les
responsables de alex/what-happens-when.</p>
<hr>
<h3 id="la-touche-g-est-appuyée">La touche &ldquo;g&rdquo; est appuyée</h3>
<p>La section suivante explique les actions physiques du clavier et les
interruptions du système d&rsquo;exploitation. Lorsque vous appuyez sur la touche
<kbd>g</kbd>, le navigateur reçoit l&rsquo;événement et les fonctions d&rsquo;autocomplétion
s&rsquo;enclenchent.</p>
<p>Selon l&rsquo;algorithme de votre navigateur et si vous êtes en mode privé, ou
non, diverses suggestions vous seront présentées dans un menu déroulant
sous la barre d&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







. La plupart des algorithmes trient et
priorisent les résultats selon la recherche historique, les marques-pages, les
cookies, et les recherches populaires sur Internet.</p>
<p>Lorsque vous écrivez <kbd>google.com</kbd>, de nombreux blocs de code s&rsquo;exécutent
et les suggestions seront affinées à chaque appui sur une touche. Il peut
même vous suggérer &ldquo;google.com&rdquo; avant que vous ayez fini de l&rsquo;écrire.</p>
<h3 id="lappui-sur-la-touche-entrée">L&rsquo;appui sur la touche &ldquo;Entrée&rdquo;</h3>
<p>Pour commencer, choisissons l&rsquo;appui sur le bas de la touche <kbd>Entrée</kbd>.</p>
<p>À ce moment, un circuit électrique spécifique à la touche est verrouillée
(soit directement, soit de manière capacitive). Ceci permet à une petite
quantité de courant de circuler dans le circuit logique du clavier, qui
analyse l&rsquo;état de l&rsquo;interrupteur de chaque touche, élimine le bruit électrique
de la fermeture intermittente rapide de l&rsquo;interrupteur et le convertit en
un entier de code de touche, en l’occurrence 13.</p>
<p>Le contrôleur du clavier encode alors le code de touche pour le transport
vers l&rsquo;ordinateur. Actuellement, c&rsquo;est presque universellement au-travers
d&rsquo;une connexion 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 ou par Bluetooth, mais historiquement c&rsquo;était
des connexions de type <a href="https://fr.wikipedia.org/wiki/Port_PS/2" rel="external">














































































<abbr lang="en" title="Personal System">PS</abbr>

































/2</a>
ou <a href="https://fr.wikipedia.org/wiki/Apple_Desktop_Bus" rel="external">


<abbr lang="en" title="Apple Desktop Bus">ADB</abbr>













































































































</a>.</p>
<p><em>Dans le cas d&rsquo;un clavier 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 :</em></p>
<ul>
<li>
<p>Le circuit USB du clavier est alimenté par l&rsquo;alimentation 5<abbr title="volt">V</abbr>

fournit sur la broche 1 du contrôleur 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 de l&rsquo;ordinateur.</p>
</li>
<li>
<p>Le code de touche généré est enregistré par la mémoire du circuit interne
du clavier dans un registre appelé &ldquo;endpoint&rdquo;.</p>
</li>
<li>
<p>Le contrôleur 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 analyse ce registre &ldquo;endpoint&rdquo; environ toutes
les 10 millisecondes <em>(valeur minimum déclarée par le clavier)</em>, ainsi il
enregistre la valeur du code de touche.</p>
</li>
<li>
<p>Cette valeur parvient au moteur d&rsquo;interface série 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 <abbr lang="en" title="Serial Interface Engine">SIE</abbr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

afin d&rsquo;être converti dans un ou plusieurs paquets 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 selon le
protocole 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 de bas niveau.</p>
</li>
<li>
<p>Ces paquets sont envoyés par un signal électrique différentiel sur les
connecteurs D+ et D- (entre 2) à la vitesse maximale de 1.5
<abbr title="Méga-octet par seconde">Mo/s</abbr>
, puisqu&rsquo;un dispositif
<a href="https://fr.wikipedia.org/wiki/Interactions_homme-machine" rel="external">


































<abbr lang="fr" title="Interface Homme-Machine">IHM</abbr>













































































</a> est toujours déclaré en tant que &ldquo;dispositif à faible
vitesse&rdquo; <em>(en conformité avec la norme 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 2.0)</em>.</p>
</li>
<li>
<p>Ce signal en série est alors décodé par le contrôleur 









































































































<abbr lang="en" title="Universal Serial Bus">USB</abbr>






 de
l&rsquo;ordinateur, puis interprété par le pilote du dispositif universel de clavier

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="fr" title="Interface Homme-Machine">IHM</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 de l&rsquo;ordinateur. La valeur de la touche est passée au-travers
de la couche d&rsquo;abstraction matérielle du système d&rsquo;exploitation.</p>
</li>
</ul>
<p><em>Dans le cas d&rsquo;un clavier virtuel (de même pour les écrans tactiles) :</em></p>
<ul>
<li>
<p>Quand l&rsquo;utilisateur pose son doigt sur un écran tactile capacitif moderne,
une quantité infime de courant est transmise au doigt. Cela complète
le circuit par le champ électrostatique de la couche conductrice et
crée une chute de tension à cet endroit de l&rsquo;écran. Le <strong>contrôleur de l&rsquo;écran</strong>
lève une interruption rapportant les coordonnées de la touche pressée.</p>
</li>
<li>
<p>Alors le système d&rsquo;exploitation mobile notifie à l&rsquo;application en cours
de l’événement de pression d&rsquo;un des éléments de son interface <em>(qui sont
les boutons de l&rsquo;interface virtuelle de l&rsquo;application de clavier)</em>.</p>
</li>
<li>
<p>Le clavier virtuel peut maintenant lever une interruption logicielle
afin d&rsquo;envoyer un message de &rsquo;touche pressée&rsquo; au système d&rsquo;exploitation.</p>
</li>
<li>
<p>Cette interruption notifie l&rsquo;application en cours d&rsquo;un événement de &rsquo;touche
pressée'.</p>
</li>
</ul>
<h3 id="déclenchement-dinterruption-hors-claviers-usb">Déclenchement d&rsquo;interruption [Hors claviers USB]</h3>
<p>Le clavier envoie des signaux sur sa ligne de requêtes d&rsquo;interruption
<em>(<a href="https://fr.wikipedia.org/wiki/Interruption_mat%C3%A9rielle" rel="external">








































<abbr lang="en" title="Interrupt ReQuest">IRQ</abbr>







































































</a>)</em>, qui correspond à un entier <code>interrupt vector</code>
du contrôleur d&rsquo;interruption.</p>
<p>Le processeur (<a href="https://fr.wikipedia.org/wiki/Processeur" rel="external">




































































































<abbr lang="fr" title="Unité Centrale de Traitement">UCT</abbr>











</a>) utilise la table de descripteurs
d&rsquo;interruptions (<a href="https://fr.wikipedia.org/wiki/Interrupt_Descriptor_Table" rel="external">

































<abbr lang="en" title="Interrupt Descriptor Table">IDT</abbr>














































































</a>) qui correspond aux vecteurs
d&rsquo;interruptions vers les fonctions <em>(<code>interrupt handlers</code>)</em> qui sont fournis
par le noyau. Lorsqu&rsquo;une interruption arrive, l&rsquo;




































































































<abbr lang="fr" title="Unité Centrale de Traitement">UCT</abbr>











 indexe
l&rsquo;

































<abbr lang="en" title="Interrupt Descriptor Table">IDT</abbr>














































































 avec le vecteur d&rsquo;interruptions et exécute le gestionnaire
approprié.</p>
<p>Ainsi, le noyau est introduit.</p>
<h3 id="dans-windows-un-message-wm_keydown-est-envoyé-à-lapplication">(Dans Windows) Un message <code>WM_KEYDOWN</code> est envoyé à l&rsquo;application</h3>
<p>Le transport 


































<abbr lang="fr" title="Interface Homme-Machine">IHM</abbr>













































































 envoie l&rsquo;événement de touche pressée au pilote
<code>KBDHID.sys</code> qui convertit l&rsquo;utilisation de l&rsquo;


































<abbr lang="fr" title="Interface Homme-Machine">IHM</abbr>













































































 vers un code
d&rsquo;analyse. Dans ce cas, le code d&rsquo;analyse est <code>VK_RETURN</code> <em>(<code>0x0D</code>)</em>.</p>
<p>Le pilote <code>KBDHID.sys</code> s&rsquo;interface avec <code>KBDCLASS.sys</code> <em>(un pilote de classe
clavier)</em>. Ce pilote est responsable de toutes les entrées de clavier et clavier
numérique de manière sécurisée. Il les appelle ensuite dans <code>Win32K.sys</code>
<em>(après avoir passer le message dans les filtres de clavier tiers installés)</em>.</p>
<p>C&rsquo;est tout ce qui se passe dans le noyau.</p>
<p><code>Win32K.sys</code> détermine quelle fenêtre est active au-travers de
l&rsquo;<a href="https://fr.wikipedia.org/wiki/Interface_de_programmation" rel="external">



<abbr lang="fr" title="Interface de Programmation Applicative">API</abbr>












































































































</a> <code>GetForegroundWindow()</code>. Cette 



<abbr lang="fr" title="Interface de Programmation Applicative">API</abbr>













































































































fournit la capture de la fenêtre à la boite d&rsquo;adresse du navigateur.</p>
<p>La fenêtre principale &ldquo;message pump&rdquo; appelle alors
<code>SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam)</code>. <code>lParam</code> est un masque
binaire qui indique des informations complémentaires à la pression de touche :
compteur de répétition <em>(<code>0</code> dans ce cas)</em>, le code d&rsquo;analyse actuel <em>(peut être
dépendant du fabriquant, mais ne l&rsquo;est pas généralement pour <code>VK_RETURN</code>)</em>,
quelque soit la touche étendue <em>(e.g. alt, shift, ctrl)</em> qui soit aussi
appuyée <em>(elles ne l&rsquo;étaient pas)</em>, ou dans un autre état.</p>
<p>L&rsquo;API Windows <code>SendMessage</code> est une fonction simple qui ajoute le message
à une queue d&rsquo;un gestionnaire de fenêtres particulier <em>(<code>hWnd</code>)</em>. Plus tard,
la fonction principale de traitement des messages <em>(appelée <code>WindowProc</code>)</em>
assignée à <code>hWnd</code> est appelée afin de traiter chaque message dans la queue.</p>
<p>La fenêtre <em>(<code>hWnd</code>)</em> qui est active est en fait un contrôleur d&rsquo;édition,
et le <code>WindowProc</code> dans ce cas est un gestionnaire de messages pour <code>WM_KEYDOWN</code>.
Ce code cherche un paramètre tiers qui est passé à <code>SendMessage</code> <em>(<code>wParam</code>)</em>,
parce que <code>VK_RETURN</code> sait qu&rsquo;un utilisateur a appuyé sur la touche
<kbd>Entrée</kbd>.</p>
<h3 id="dans-os-x-un-nsevent-keydown--est-envoyé-à-lapplication">(Dans OS X) Un NSEvent <code>KeyDown</code>  est envoyé à l&rsquo;application</h3>
<p>Le signal d&rsquo;interruption déclenche un événement d&rsquo;interruption dans le pilote
du Kit d&rsquo;Entrée/Sortie (I/O) kext du clavier. Le pilote traduit le signal
dans un code de touche qui est passée au process d&rsquo;OS X <code>WindowServer</code>.</p>
<p>Pour résultat, le <code>WindowServer</code> envoie un événement à toute application
appropriée <em>(e.g. active ou écoutant)</em> au-travers du port Mach qui est placé
dans la queue d&rsquo;événements. Les événements peuvent alors être lus depuis
cette queue par des &ldquo;fils&rdquo; <em>(appelés threads)</em> disposant des privilèges
suffisants appelant la fonction <code>mach_ipc_dispatch</code>.</p>
<p>Cela arrive généralement au-travers d&rsquo;une boucle de gestion principale
<code>NSApplication</code> le gérant, via un événement <code>NSEvent</code> d&rsquo;un type d&rsquo;événement
<code>NSEventType</code> <code>KeyDown</code>.</p>
<h3 id="dans-gnulinux-le-serveur-xorg-écoute-les-codes-de-touches">(Dans GNU/Linux) Le serveur Xorg écoute les codes de touches</h3>
<p>Lorsqu&rsquo;un serveur graphique <code>X server</code> est utilisé, <code>X</code> utilisera
le pilote d&rsquo;événement générique <code>evdev</code> afin d&rsquo;acquérir l&rsquo;événement de
pression de touche. La conversion des codes de touches en codes d&rsquo;analyse
est faite à l&rsquo;aide de règles et de keymaps <em>(&ldquo;cartes de claviers&rdquo;)</em> spécifiques
à <code>X server</code>.</p>
<p>Lorsque la correspondance du code d&rsquo;analyse à une touche pressée est complète,
le <code>X server</code> envoie le caractère au gestionnaire de fenêtres <code>window manager</code>
<em>(DWM, metacity, i3, etc)</em>, afin que le <code>window manager</code> à son tour envoie
le caractère à la fenêtre en cours.</p>
<p>L&rsquo;



<abbr lang="fr" title="Interface de Programmation Applicative">API</abbr>












































































































 graphique de la fenêtre qui reçoit le caractère affiche le
symbole de police approprié dans le champ approprié ayant le focus.</p>
<h3 id="analyse-durl">Analyse d&rsquo;URL</h3>
<ul>
<li>
<p>Le navigateur a maintenant l&rsquo;information suivante contenue dans
l&rsquo;<a href="https://fr.wikipedia.org/wiki/Uniform_Resource_Locator" rel="external">








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







</a> :</p>
<ul>
<li><strong>Protocole</strong> &ldquo;http&rdquo; : Utilise &ldquo;<a href="https://fr.wikipedia.org/wiki/Hypertext_Transfer_Protocol" rel="external">































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































</a>&rdquo;</li>
<li><strong>Ressource</strong> &ldquo;/&rdquo; : Récupère la page principale (index)</li>
</ul>
</li>
</ul>
<h3 id="est-ce-une-url-ou-un-terme-recherché-">Est-ce une URL ou un terme recherché ?</h3>
<p>Quand aucun protocole ou nom de domaine valide n&rsquo;est donné, le navigateur
s&rsquo;occupe de récupérer le texte donné dans la boite d&rsquo;adresse au moteur de
recherche web par défaut du navigateur.</p>
<p>Dans beaucoup de cas, un texte spécial est ajouté à l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







 pour
indiquer au moteur de recherche qu&rsquo;il provient de la barre d&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>








d&rsquo;un navigateur particulier.</p>
<h3 id="convertir-les-caractères-unicode-non-ascii-dans-le-nom-dhôte">Convertir les caractères Unicode non-ASCII dans le nom d&rsquo;hôte</h3>
<ul>
<li>
<p>Le navigateur vérifie tous les caractères du nom d&rsquo;hôte, qui ne soient pas
<code>a-z</code>,  <code>A-Z</code>, <code>0-9</code>, <code>-</code>, ou <code>.</code>.</p>
</li>
<li>
<p>Puisque le nom d&rsquo;hôte est <code>google.com</code>, il n&rsquo;y en aura pas ; mais si
c&rsquo;était le cas, le navigateur appliquerait l&rsquo;encodage <a href="https://fr.wikipedia.org/wiki/Punycode" rel="external">Punycode</a> à la
portion du nom d&rsquo;hôte dans l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







.</p>
</li>
</ul>
<h3 id="vérifier-la-liste-hsts">Vérifier la liste HSTS</h3>
<ul>
<li>
<p>Le navigateur vérifie sa liste de &ldquo;<a href="https://fr.wikipedia.org/wiki/HTTP_Strict_Transport_Security" rel="external"><abbr title="">HSTS</abbr>
</a> préchargés&rdquo;. <br>
C&rsquo;est une liste de sites web qui ont requis de n&rsquo;être contactés seulement
que sur <a href="https://fr.wikipedia.org/wiki/HyperText_Transfer_Protocol_Secure" rel="external">
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































</a>.</p>
</li>
<li>
<p>Si le site web est dans la liste, le navigateur envoie sa requête via

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 plutôt qu&rsquo;en 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































. Autrement, la requête
initiale est envoyée en 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































. <br>
<em>(Notez qu&rsquo;un site web peut toujours utiliser une politique <abbr title="">HSTS</abbr>

<em>sans</em> être dans la liste <abbr title="">HSTS</abbr>
. La première requête

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 au site web faite par un utilisateur recevra une réponse
demandant que l&rsquo;utilisateur envoie seulement des requêtes 
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































.
Toutefois, cette unique requête 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 pourrait potentiellement
laisser l&rsquo;utilisateur vulnérable à une attaque dite <a href="https://fr.wikipedia.org/wiki/Moxie_Marlinspike#HTTPS_stripping" rel="external"><code>downgrade attack</code></a> ;
c&rsquo;est la raison pour laquelle la liste <abbr title="">HSTS</abbr>
 est incluse dans les
navigateurs web modernes)</em>.</p>
</li>
</ul>
<h3 id="recherche-dns">Recherche DNS</h3>
<ul>
<li>
<p>Le navigateur vérifie si le domaine est dans son cache. <em>(Pour voir le
cache 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 dans Chrome, écrivez dans la barre d&rsquo;adresse
<code>chrome://net-internals/#dns</code>)</em>.</p>
</li>
<li>
<p>S&rsquo;il n&rsquo;est pas trouvé, le navigateur appelle la fonction de bibliothèque
<code>gethostbyname</code> <em>(qui varie selon l&rsquo;OS)</em> afin de faire la recherche.</p>
</li>
<li>
<p><code>gethostbyname</code> vérifie si le nom d&rsquo;hôte peut être résolu par référence
dans le fichier local <code>hosts</code> <em>(dont la localisation <a href="https://fr.wikipedia.org/wiki/Hosts#Localisation" rel="external">varie selon l&rsquo;OS</a>)</em>
avant d&rsquo;essayer de résoudre le nom d&rsquo;hôte au-travers <a href="https://fr.wikipedia.org/wiki/Domain_Name_System" rel="external">
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































</a>.</p>
</li>
<li>
<p>Si <code>gethostbyname</code> ne le trouve pas dans le cache, ni dans le fichier
<code>hosts</code> alors elle fait une requête vers le serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>
































































































configuré dans la pile réseau. C&rsquo;est typiquement le routeur local ou le
serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 cache du <a href="https://fr.wikipedia.org/wiki/Fournisseur_d%27acc%C3%A8s_%C3%A0_Internet" rel="external">






















<abbr lang="fr" title="Fournisseur d&#39;Accès Internet">FAI</abbr>

























































































</a>.</p>
</li>
<li>
<p>Si le serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 est sur le même sous-réseau, la bibliothèque
réseau suit le <code>processus 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</code> décrit ci-dessous pour le
serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































.</p>
</li>
<li>
<p>Si le serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 est sur un sous-réseau différent, la
bibliothèque réseau suit le <code>processus 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</code> décrit ci-dessous
pour l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 de la passerelle par défaut.</p>
</li>
</ul>
<h3 id="processus-arp">Processus ARP</h3>
<p>Avant d&rsquo;envoyer une diffusion <a href="https://fr.wikipedia.org/wiki/Address_Resolution_Protocol" rel="external">




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</a>, la bibliothèque de la
pile réseau a besoin de l&rsquo;<a href="https://fr.wikipedia.org/wiki/Adresse_IP" rel="external">adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































</a> cible à rechercher.
Elle doit aussi connaître l&rsquo;<a href="https://fr.wikipedia.org/wiki/Adresse_MAC" rel="external">adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































</a> de l&rsquo;interface
qu&rsquo;elle utilisera pour envoyer la diffusion 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































.</p>
<p>Le cache 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 est vérifié en premier pour trouver une entrée





<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 de notre 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 cible. Si elle est dans le cache,
la bibliothèque retourne le résultat : 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 cible = 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































.</p>
<p>Si l&rsquo;entrée n&rsquo;est pas dans le cache 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 :</p>
<ul>
<li>
<p>La table de routage est recherchée, pour voir si l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>













































































ciblée est dans le sous-réseau de la table de routage local. Si elle y est,
la bibliothèque utilise l&rsquo;interface associée au sous-réseau. Si elle n&rsquo;y
est pas, la bibliothèque utilise l&rsquo;interface qui est dans le sous-réseau
de notre passerelle par défaut.</p>
</li>
<li>
<p>L&rsquo;adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































 de l&rsquo;interface réseau sélectionnée est recherchée.</p>
</li>
<li>
<p>La bibliothèque réseau envoie une <a href="/fr/trad/que-se-passe-t-il-quand-vous-ecrivez-dans-la-barre-d-adresse-du-navigateur-web/#requête-arp">requête 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</a>
de la Couche de Liaison 2 <em>(trame de liaison d&rsquo;adressage physique du
<a href="https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI" rel="external">modèle 





































































<abbr lang="en" title="Open Systems Interconnection">OSI</abbr>










































</a>)</em> :</p>
</li>
</ul>
<h4 id="requête-arp">Requête ARP</h4>
<ul>
<li>Émetteur 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































: <code>interface:mac:address:here</code></li>
<li>Émetteur 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































: <code>interface.ip.goes.here</code></li>
<li>Cible 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































: <code>FF:FF:FF:FF:FF:FF</code> <em>(Broadcast)</em></li>
<li>Cible 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































: <code>target.ip.goes.here</code></li>
</ul>
<p>Cela dépend du type de matériel qui est entre l&rsquo;ordinateur et le routeur :</p>
<p>⇒ Directement connecté :</p>
<ul>
<li>Si l&rsquo;ordinateur est directement connecté au routeur, le routeur répond
avec une &ldquo;<a href="/fr/trad/que-se-passe-t-il-quand-vous-ecrivez-dans-la-barre-d-adresse-du-navigateur-web/#réponse-arp">réponse 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</a> <em>(lire ci-dessous)</em></li>
</ul>
<p>⇒ Par un Hub :</p>
<ul>
<li>Si l&rsquo;ordinateur est connecté à un hub, le hub diffusera la requête

  
  
  
  
  <abbr lang="en" title="Address Resolution Protocol">ARP</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 vers tous les autres ports. Si le routeur est connecté sur
la même &ldquo;interface&rdquo;, il répondra avec une &ldquo;<a href="/fr/trad/que-se-passe-t-il-quand-vous-ecrivez-dans-la-barre-d-adresse-du-navigateur-web/#réponse-arp">réponse 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</a>&rdquo;
<em>(lire ci-dessous)</em>.</li>
</ul>
<p>⇒ Par un commutateur :</p>
<ul>
<li>
<p>Si l&rsquo;ordinateur est connecté à un commutateur, le commutateur vérifiera sa
table 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































 pour savoir sur quel port est diffusé l&rsquo;adresse

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Message Authentication Code">MAC</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 recherchée. <br>
Si le commutateur n&rsquo;a pas d&rsquo;entrée pour l&rsquo;adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































, il
rediffusera la requête 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 vers tous les autres ports.</p>
</li>
<li>
<p>Si le commutateur a une entrée dans la table 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































, il enverra
une requête 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 au port correspondant à l&rsquo;adresse

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Message Authentication Code">MAC</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 recherchée.</p>
</li>
<li>
<p>Si le routeur est sur la même &ldquo;interface&rdquo;, il répondra avec une
&ldquo;<a href="/fr/trad/que-se-passe-t-il-quand-vous-ecrivez-dans-la-barre-d-adresse-du-navigateur-web/#réponse-arp">réponse 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































</a>&rdquo; <em>(lire ci-dessous)</em></p>
</li>
</ul>
<h4 id="réponse-arp">Réponse ARP</h4>
<ul>
<li>Émetteur 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































: <code>target:mac:address:here</code></li>
<li>Émetteur 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































: <code>target.ip.goes.here</code></li>
<li>Cible 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































: <code>interface:mac:address:here</code></li>
<li>Cible 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































: <code>interface.ip.goes.here</code></li>
</ul>
<hr>
<p><em>Le protocole 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 est nécessaire au fonctionnement
d’<a href="https://fr.wikipedia.org/wiki/Internet_Protocol" rel="external">





































<abbr lang="en" title="Internet Protocol v4">IPv4</abbr>










































































</a>, utilisé par dessus un réseau de type Ethernet. En
<a href="https://fr.wikipedia.org/wiki/IPv6" rel="external">






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































</a>, les fonctions 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 ont été reprises dans
le processus de découverte <a href="https://fr.wikipedia.org/wiki/Neighbor_Discovery_Protocol" rel="external">
































































<abbr lang="en" title="Neighbor Discovery Protocol">NDP</abbr>















































</a></em></p>
<hr>
<p>Maintenant que la bibliothèque réseau a l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































, soit de
notre serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































, soit de la passerelle par défaut, elle peut
reprendre son processus 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 :</p>
<ul>
<li>
<p>Le client 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 établit un socket vers le port 





































































































<abbr lang="en" title="User Datagram Protocol">UDP</abbr>











53 du serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































, utilisant un port source au-delà de 1023.</p>
</li>
<li>
<p>Si la taille de la réponse est trop grande, 





























































































<abbr lang="en" title="Transfer Control Protocol">TCP</abbr>


















 sera utilisé à
la place.</p>
</li>
<li>
<p>Si le serveur 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































 local ou du 






















<abbr lang="fr" title="Fournisseur d&#39;Accès Internet">FAI</abbr>

























































































 ne l&rsquo;a pas,
alors une recherche récursive est requise et fait remonter la liste des
serveurs 
















<abbr lang="en" title="Domain Name Service">DNS</abbr>































































































, et qu&rsquo;une réponse soit retournée.</p>
</li>
</ul>
<h3 id="ouverture-dune-socket">Ouverture d&rsquo;une socket</h3>
<p>Une fois que le navigateur reçoit l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 du serveur de
destination, il la prend ainsi que le numéro de port donné dans l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>








<em>(par défaut, le protocole 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 a le port 80, et 
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>
















































































le port 443)</em>, puis fait un appel à la fonction de la bibliothèque système
nommée <code>socket</code> et requiert un flux de socket 





























































































<abbr lang="en" title="Transfer Control Protocol">TCP</abbr>


















 -
<code>AF_INET/AF_INET6</code> et <code>SOCK_STREAM</code>.</p>
<ul>
<li>
<p>Cette requête est en premier passé à la Couche de Transport où un segment

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Transfer Control Protocol">TCP</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 est créé. Le port de destination est ajouté à l&rsquo;entête, et
le port source est choisi parmi une plage de port dynamique du noyau
<em>(<code>ip_local_port_range</code> dans Linux)</em>.</p>
</li>
<li>
<p>Ce segment est envoyé vers la Couche Réseau, qui enveloppe une entête

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Internet Protocol">IP</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   additionnelle. L&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 du serveur cible
aussi bien que celle de la machine courante est insérée pour former un paquet.</p>
</li>
<li>
<p>Le paquet suivant arrive sur la Couche de Liaison. Une entête de trame est
ajouté qui inclut l&rsquo;adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































 de l&rsquo;interface réseau de la
machine ainsi que l&rsquo;adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>



























































 de la passerelle <em>(le routeur
local)</em>. Tout comme avant, si le noyau ne connaît pas l&rsquo;adresse 




















































<abbr lang="en" title="Message Authentication Code">MAC</abbr>




























































de la passerelle, il doit diffuser une requête 




<abbr lang="en" title="Address Resolution Protocol">ARP</abbr>











































































































 pour la trouver.</p>
</li>
</ul>
<p>À partir de ce point, le paquet est prêt à être transmis, soit au-travers :</p>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/IEEE_802.3" rel="external">Ethernet</a></li>
<li><a href="https://fr.wikipedia.org/wiki/IEEE_802.11" rel="external">WiFi</a></li>
<li><a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_de_t%C3%A9l%C3%A9phonie_mobile" rel="external">Réseau de Téléphonie Mobile</a></li>
</ul>
<p>Pour la plupart des connexions à Internet depuis une maison, ou pour de
petites entreprises, le paquet passera de votre ordinateur, possiblement
au-travers du réseau local, puis vers un 


























































<abbr lang="fr" title="MOdulateur/DEModulateur">modem</abbr>





















































 qui convertit les
0 et 1 numériques en signal analogique adapté à la transmission par téléphone,
câble ou connexions de téléphonie sans fil.</p>
<p>À l&rsquo;autre extrémité de la connexion se trouve un autre modem qui reconvertit
le signal analogique en données numériques qui seront traitées par le
prochain <a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_informatique" rel="external">nœud de réseau</a> où les adresses de départ et d&rsquo;arrivée seront
analysées plus en détail.</p>
<p>La plupart des grandes entreprises et certaines connexions résidentielles
plus récentes disposeront de connexions en fibre optique ou de connexions
Ethernet directes, auxquels cas les données restent numériques et sont
transmises directement au prochain <a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_informatique" rel="external">nœud de réseau</a> pour y être traitées.</p>
<p>Éventuellement, le paquet atteindra le routeur gérant le sous-réseau local.
Depuis là, il continuera à voyager vers l&rsquo;<a href="https://fr.wikipedia.org/wiki/Autonomous_System" rel="external">





<abbr lang="fr" title="Système Autonome">AS</abbr>










































































































</a> au-delà
du routeur, vers d&rsquo;autres 





<abbr lang="fr" title="Système Autonome">AS</abbr>










































































































, et finalement atteindra le serveur
de destination.</p>
<p>Chaque routeur, le long du chemin, extrait l&rsquo;adresse de destination de
l&rsquo;entête d&rsquo;



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 et la dirige vers le prochain saut approprié.</p>
<p>Le champ <a href="https://fr.wikipedia.org/wiki/Time_to_Live#Le_Time_to_Live_sur_les_paquets_IP" rel="external">



































































































<abbr lang="en" title="Time to Live">TTL</abbr>












</a> dans l&rsquo;entête de l&rsquo;



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 est
décrémenté de un à chaque routeur traversé. Le paquet sera supprimé si le champ




































































































<abbr lang="en" title="Time to Live">TTL</abbr>












 atteint zéro ou si le routeur en cours n&rsquo;a plus d&rsquo;espace dans
sa queue <em>(cela peut être dû à une congestion du réseau)</em>.</p>
<p>Cet envoi et cette réception arrive de nombreuses fois suivant le flux de
connexion 





























































































<abbr lang="en" title="Transfer Control Protocol">TCP</abbr>


















 :</p>
<ul>
<li>
<p>Le client choisit un <a href="https://fr.wikipedia.org/wiki/Transmission_Control_Protocol#Num%C3%A9ros_de_s%C3%A9quence_et_d&#39;acquittement" rel="external">










































<abbr lang="fr" title="Numéro de Séquence Initial">ISN</abbr>





































































</a>
et envoie le paquet au serveur avec le bit SYN paramétré pour indiquer
qu&rsquo;il active l&rsquo;










































<abbr lang="fr" title="Numéro de Séquence Initial">ISN</abbr>





































































.</p>
</li>
<li>
<p>Le serveur reçoit le bit SYN et s&rsquo;il est &ldquo;d&rsquo;humeur agréable&rdquo; :</p>
<ul>
<li>le serveur choisit son propre numéro de séquence initial</li>
<li>le serveur paramètre le bit SYN afin d&rsquo;indiquer qu&rsquo;il a choisit son

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    <abbr lang="fr" title="Numéro de Séquence Initial">ISN</abbr>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
</li>
<li>le serveur copie l&rsquo;










































<abbr lang="fr" title="Numéro de Séquence Initial">ISN</abbr>





































































 du client +1 dans son champ ACK et
ajoute le drapeau ACK afin d&rsquo;indiquer qu&rsquo;il accuse réception du premier
paquet.</li>
</ul>
</li>
<li>
<p>Le client reconnaît la connexion en envoyant un paquet :</p>
<ul>
<li>augmentant son propre numéro de séquence</li>
<li>augmentant le numéro d&rsquo;accusé de réception</li>
<li>paramètre le champ ACK</li>
</ul>
</li>
<li>
<p>La donnée est transmise ainsi :</p>
<ul>
<li>Lorsqu&rsquo;une partie envoie N octets de données, elle augmente sa séquence
SEQ par un numéro</li>
<li>Quand l&rsquo;autre partie accuse réception du paquet (ou d&rsquo;une chaîne de
paquets), elle envoie un paquet ACK avec une valeur ACK égale à la
dernière séquence reçue depuis l&rsquo;autre partie.</li>
</ul>
</li>
<li>
<p>Pour fermer la connexion :</p>
<ul>
<li>la partie qui termine la connexion envoie un paquet FIN.</li>
<li>l&rsquo;autre partie accuse réception ACK du paquet FIN et envoie son propre
paquet FIN.</li>
<li>la première partie accuse réception ACK du paquet FIN de l&rsquo;autre partie.</li>
</ul>
</li>
</ul>
<h3 id="la-poignée-de-main-tls">La Poignée de Main TLS</h3>
<ul>
<li>
<p>L&rsquo;ordinateur client envoie un message <code>ClientHello</code> au serveur avec sa
version de <a href="https://fr.wikipedia.org/wiki/Transport_Layer_Security" rel="external">
































































































<abbr lang="en" title="Transport Layer Secure">TLS</abbr>















</a>, une liste d&rsquo;algorithmes de chiffrement
et de méthodes de compression disponibles.</p>
</li>
<li>
<p>Le serveur répond avec un message <code>ServerHello</code> au client avec la version

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Transport Layer Secure">TLS</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
, le chiffrement choisi, les méthodes de compression
sélectionnées et le certificat public signé par une <a href="https://fr.wikipedia.org/wiki/Autorit%C3%A9_de_certification" rel="external">

<abbr lang="fr" title="Autorité de Certification">AC</abbr>














































































































</a>
du serveur. <br>
Le certificat contient une clé publique qui sera utilisée par le client
pour chiffrer le reste de la poignée de main jusqu&rsquo;à ce qu&rsquo;une clé symétrique
puisse être convenue.</p>
</li>
<li>
<p>Le client vérifie que le certificat numérique du serveur soit dans sa
liste d&rsquo;

<abbr lang="fr" title="Autorité de Certification">AC</abbr>














































































































 de confiance. Si la confiance peut être établie,
basée sur l&rsquo;

<abbr lang="fr" title="Autorité de Certification">AC</abbr>














































































































, le client génère une chaîne d&rsquo;octets
pseudo-aléatoires et la chiffre avec la clé publique du serveur. Ces octets
aléatoires peuvent être utilisés pour déterminer la clé symétrique.</p>
</li>
<li>
<p>Le serveur déchiffre les octets aléatoires en utilisant sa clé privée
puis utilise ces octets pour générer sa propre copie de la clé symétrique
maître.</p>
</li>
<li>
<p>Le client envoie un message <code>Finished</code> au serveur, chiffrant un hash
de la transmission jusqu&rsquo;à ce point avec la clé symétrique.</p>
</li>
<li>
<p>Le serveur génère son propre hash, puis déchiffre le hash envoyé par le
client pour vérifier la correspondance. Si elle existe, il envoie son
propre message <code>Finished</code> au client, le chiffrant aussi avec sa clé
symétrique.</p>
</li>
<li>
<p>À partir de maintenant la session 
































































































<abbr lang="en" title="Transport Layer Secure">TLS</abbr>















 transmet les données de
l&rsquo;application <em>(































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































)</em> chiffrées avec la clé symétrique agréée.</p>
</li>
</ul>
<h3 id="protocole-http">Protocole HTTP</h3>
<p>Si le navigateur web utilisé été écrit par Google, au lieu d&rsquo;envoyer une
requête HTTP pour récupérer la page, il enverra une requête pour négocier
avec le serveur une &ldquo;mise à jour&rdquo; du protocole 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 vers le
protocole <a href="https://fr.wikipedia.org/wiki/SPDY" rel="external">
























































































<abbr lang="en" title="Speedy">SPDY</abbr>























</a>.</p>
<p>Si le client utilise le protocole 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 mais ne prend pas en
charge 
























































































<abbr lang="en" title="Speedy">SPDY</abbr>























, il envoie une requête au serveur de la forme :</p>
<pre tabindex="0"><code>GET / HTTP/1.1
Host: google.com
Connection: close
[autres entêtes]
</code></pre><p>où <code>[autres entêtes]</code> référent à une série de paire de clé et valeur séparée
par le symbole deux points &lsquo;:&rsquo;, formatées selon la spécification
































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 et séparées par d&rsquo;uniques nouvelles lignes. <br>
<em>(Cela suppose que le navigateur web utilisé n&rsquo;ait pas de bogues violant la
spécification 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































. Cela suppose aussi que le navigateur web
utilise <code>HTTP/1.1</code>, autrement il ne pourrait pas inclure l&rsquo;entête <code>Host</code>
dans la requête ; la version spécifiée dans la requête <code>GET</code> serait soit
<code>HTTP/1.0</code> ou <code>HTTP/0.9</code>.)</em></p>
<p>































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































/1.1 définit l&rsquo;option de &ldquo;fermeture&rdquo; de la connexion pour que
l&rsquo;expéditeur signale que la connexion sera fermée après l&rsquo;achèvement de la
réponse. <br>
Par exemple :</p>
<p><code>Connection: close</code></p>
<p>Les applications 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































/1.1 qui ne prennent pas en charge les
connexions persistantes DOIVENT inclure l&rsquo;option de &ldquo;fermeture&rdquo; de connexion
dans chaque message.</p>
<p>Après l&rsquo;envoi de la requête et des entêtes, le navigateur web envoie une
unique nouvelle ligne vierge pour indiquer au serveur que le contenu de
la requête est fait.</p>
<p>Le serveur répond avec un code de réponse dénotant le statut de la requête
et avec une réponse de la forme :</p>
<pre tabindex="0"><code>200 OK
[entêtes de réponse]
</code></pre><p>Suivies d&rsquo;une unique nouvelle ligne, il envoie alors la charge du contenu






























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 de <code>www.google.com</code>. Le serveur peut alors soit fermer la
connexion, soit si les entêtes envoyées par le client le demande, garder la
connexion ouverte afin d&rsquo;être réutilisées pour de prochaines requêtes.</p>
<p>Si les entêtes 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































 envoyées par le navigateur web comportent des
informations suffisantes pour que le serveur web détermine si la version du
fichier en cache dans le navigateur web n&rsquo;a pas été modifié depuis la dernière
récupération <em>(tel que si le navigateur web inclut une entête <code>ETag</code>)</em>, il
peut alors répondre par une requête de la forme :</p>
<pre tabindex="0"><code>304 Not Modified
[entêtes de réponse]
</code></pre><p>il n&rsquo;y aura pas charge utile, et le navigateur web récupérera le 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>



















































































depuis son cache.</p>
<p>Après l&rsquo;analyse du 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, le navigateur web <em>(ainsi que le serveur)</em>
répétera ce processus pour chaque ressource <em>(image, CSS, favicon.ico, etc)</em>
référencée dans la page 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, excepté que la requête sera
<code>GET /$(URL relative à www.google.com) HTTP/1.1</code> au lieu de <code>GET / HTTP/1.1</code>.</p>
<p>Si le 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 référence une ressource sur un domaine différent que
<code>www.google.com</code>, le navigateur web reprendra les étapes invoquées pour
résoudre l&rsquo;autre domaine, et suivra toutes les mêmes étapes jusqu&rsquo;à ce point
pour ce domaine. <br>
L&rsquo;entête <code>Host</code> dans la requête sera paramétrée vers le nom du serveur
approprié plutôt que <code>google.com</code>.</p>
<h3 id="gestionnaire-de-requêtes-http-du-serveur">Gestionnaire de Requêtes HTTP du Serveur</h3>
<p>Le serveur HTTPD <em>(Service HTTP)</em> est un gestionnaire de requêtes et de réponses
côté serveur. Les serveurs HTTPD des plus communs sont Apache ou nginx pour
Linux et IIS pour Windows.</p>
<ul>
<li>
<p>Le serveur HTTPD <em>(Service HTTP)</em> reçoit la requête.</p>
</li>
<li>
<p>Le serveur décompose la requête selon les paramètres suivants :</p>
<ul>
<li>la méthode de requête HTTP <em>(soit <code>GET</code>, <code>HEAD</code>, <code>POST</code>, <code>PUT</code>,
<code>PATCH</code>, <code>DELETE</code>, <code>CONNECT</code>, <code>OPTIONS</code>, ou <code>TRACE</code>)</em>. Dans
le cas où l&rsquo;URL est entrée directement dans la barre d&rsquo;adresse, elle
sera <code>GET</code>.</li>
<li>le domaine ; dans ce cas : google.com</li>
<li>le chemin ou la page demandé ; dans ce cas : / <em>(puisqu&rsquo;il n&rsquo;y a pas
de chemin ou de page spécifique demandé, / est le chemin par défaut)</em>.</li>
</ul>
</li>
<li>
<p>Le serveur vérifie qu&rsquo;un Hôte Virtuel soit configuré sur le serveur
correspondant à google.com.</p>
</li>
<li>
<p>Le serveur vérifie que google.com peut accepter les requêtes GET.</p>
</li>
<li>
<p>Le serveur vérifie que le client est autorisé à utiliser cette méthode
<em>(par l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































, authentification, etc)</em>.</p>
</li>
<li>
<p>Si le serveur a un module de ré-écriture installé <em>(tel que mod_rewrite
pour Apache ou URL Rewrite pour IIS)</em>, il essaiera la correspondance de
la requête avec une des règles configurées. Si une règle correspondante
est trouvée, le serveur utilise la règle pour ré-écrire la requête.</p>
</li>
<li>
<p>Le serveur envoie le contenu qui correspond à la requête, dans notre cas,
il reviendra au fichier index, puisque &ldquo;/&rdquo; est le fichier principal
<em>(dans certains cas, cela peut être surchargé, mais c&rsquo;est la méthode commune)</em>.</p>
</li>
<li>
<p>Le serveur analyse le fichier en accord avec le gestionnaire. Si Google
exécute PHP, le serveur utilise PHP pour interpréter le fichier index,
et envoie le flux vers le client.</p>
</li>
</ul>
<h3 id="la-scène-derrière-le-navigateur">La scène derrière le Navigateur</h3>
<p>Une fois que le serveur délivre les ressources <em>(





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































,












<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, 













































<abbr lang="en" title="JavaScript">JS</abbr>


































































, images, etc)</em> au navigateur, il est soumis
au processus suivant :</p>
<ul>
<li>Analyse 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, 













































<abbr lang="en" title="JavaScript">JS</abbr>


































































</li>
<li>Rendu : construit l&rsquo;arborescence 



















<abbr lang="en" title="Document Object Model">DOM</abbr>




























































































 → l&rsquo;arborescence de rendu
→ le plan de l&rsquo;arborescence de rendu → l&rsquo;affichage de l&rsquo;arborescence de
rendu</li>
</ul>
<h3 id="le-navigateur">Le Navigateur</h3>
<p>La fonction du navigateur est de présenter la ressource web que vous avez
choisi, en la demandant à un serveur et en l&rsquo;affichant dans la fenêtre du
navigateur. La ressource est habituellement un document 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































,
mais peut être aussi un PDF, une image, ou tout autre type de contenu. <br>
L&rsquo;endroit de la ressource est spécifié par l&rsquo;utilisateur selon une
















































































































.</p>
<p>La manière dont le navigateur interprète et affiche les fichiers






























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 est spécifiée dans les spécifications 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 et












<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































. Ces spécifications sont maintenues par le 













































































































<abbr lang="en" title="World Wide Web Consortium">W3C</abbr>


,
qui est l&rsquo;organisation des standards du web.</p>
<p>Les interfaces utilisateur de navigation ont beaucoup en commun entre elles.
Parmi les éléments communs de l&rsquo;interface utilisateur, on peut citer :</p>
<ul>
<li>une barre d&rsquo;adresse pour l&rsquo;insertion d&rsquo;une 















































































































</li>
<li>des boutons de retour et d&rsquo;avance</li>
<li>des options de marque-pages <em>(favoris)</em></li>
<li>des boutons pour rafraîchir et stopper le chargement de documents en cours</li>
<li>un bouton d’accueil pour vous permettre d&rsquo;aller à votre page d&rsquo;accueil.</li>
</ul>
<p><strong>Structure de Haut Niveau du Navigateur</strong></p>
<p>Les composants des navigateurs sont :</p>
<ul>
<li>
<p><strong>Une Interface Utilisateur</strong> : l&rsquo;interface utilisateur <em>(UI)</em> inclue la barre
d&rsquo;adresse, les boutons retour/avance, le menu des marque-pages, etc.
Chaque partie du navigateur s&rsquo;affiche, exceptée la fenêtre où vous voyez
la page demandée.</p>
</li>
<li>
<p><strong>Le Moteur du Navigateur</strong> : le moteur du navigateur répartit les actions
entre l&rsquo;UI et le moteur de rendu.</p>
</li>
<li>
<p><strong>Le Moteur de Rendu</strong> : le moteur de rendu est responsable d&rsquo;afficher
le contenu demandé. Par exemple, si le contenu demandé est du

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="HyperText Markup Language">HTML</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
, le moteur de rendu analyse le 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 et le

  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Cascade Style Sheet">CSS</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
, et affiche le contenu analysé à l&rsquo;écran.</p>
</li>
<li>
<p><strong>Réseau</strong> : le réseau gère les appels réseau tels que les requêtes

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 utilisant différentes implémentations pour les différentes
plateformes derrière une interface de plateforme indépendante.</p>
</li>
<li>
<p><strong>Backend UI</strong> : le backend de l&rsquo;UI est utilisé pour dessiner les widgets
basiques tels que les comboboxes et les fenêtres. Ce backend expose une
interface générique qui n&rsquo;est pas spécifique à une plateforme. <br>
En profondeur, il utilise les méthodes de l&rsquo;interface utilisateur du
système d&rsquo;exploitation.</p>
</li>
<li>
<p><strong>Le Moteur JavaScript</strong> : le moteur JavaScript est utilisé pour analyser
et exécuter le code JavaScript.</p>
</li>
<li>
<p><strong>Le Stockage des Données</strong> : le stockage des données est une couche
persistante. <br>
Le navigateur peut sauvegarder toute sorte de données localement, tels
que des cookies. Les navigateurs prennent en charge aussi des mécanismes
de stockage tels que localStorage, IndexedDB, WebSQL et FileSystem.</p>
</li>
</ul>
<h3 id="analyse-du-html">Analyse du HTML</h3>
<p>Le moteur de rendu démarre l&rsquo;obtention des contenus du document demandé
depuis la couche réseau. Cela se fait habituellement par morceaux de 8 Ko.</p>
<p>Le premier travail de l&rsquo;analyseur HTML est d&rsquo;analyser le langage






























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 dans une arborescence.</p>
<p>La sortie de l&rsquo;arborescence <em>(&ldquo;l&rsquo;arborescence analysée&rdquo;)</em> est une arborescence
des éléments du 



















<abbr lang="en" title="Document Object Model">DOM</abbr>




























































































 et des nœuds d&rsquo;attributs. 



















<abbr lang="en" title="Document Object Model">DOM</abbr>





























































































est l&rsquo;abréviation de Document Object Model. C&rsquo;est la présentation objet du
document 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 et l&rsquo;interface des éléments 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 au
monde extérieur tel JavaScript. La racine de l&rsquo;arborescence est l&rsquo;objet &ldquo;Document&rdquo;.</p>
<p>Avant toute manipulation par script, le 



















<abbr lang="en" title="Document Object Model">DOM</abbr>




























































































 a une relation
quasi-univoque avec le balisage.</p>
<p><strong>Algorithme d&rsquo;Analyse</strong></p>
<p>Le 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 ne peut être analysé par des analyseurs habituels.</p>
<p>Les raisons sont :</p>
<ul>
<li>la nature indulgente du langage.</li>
<li>le fait que les navigateurs ont une tolérance traditionnelle à l&rsquo;erreur
pour prendre en charge les cas connus de 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 invalides.</li>
<li>le processus d&rsquo;analyse est ré-entrant. Pour les autres langages, la source
ne change pas durant l&rsquo;analyse, mais en 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, le code dynamique
<em>(tels que des éléments de scripts contenant des appels à <code>document.write()</code>)</em>
peut ajouter des jetons supplémentaires ; le processus d&rsquo;analyse en cours
modifie alors l&rsquo;entrée.</li>
</ul>
<p>Si le navigateur est incapable d&rsquo;utiliser les techniques d&rsquo;analyses régulières,
il utilisera un analyseur personnalisé pour l&rsquo;analyse 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































.
L&rsquo;algorithme d&rsquo;analyse est décrit en détail par la spécification






























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































5.</p>
<p>L&rsquo;algorithme consiste en deux phases : mise en jeton et construction de
l&rsquo;arborescence.</p>
<p><strong>Les Actions lorsque l&rsquo;Analyse est terminée</strong></p>
<p>Le navigateur commence par récupérer les ressources externes liées à la page
<em>(











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, images, fichiers JavaScript, etc)</em>.</p>
<p>Lors de cette étape, le navigateur marque le document comme interactif et
démarre les scripts d&rsquo;analyse qui sont dans le mode &ldquo;différé&rdquo; : tout ce
qui doit être exécuté après le document est analysé. L&rsquo;état du document
est paramétré sur &ldquo;complet&rdquo; et un événement &ldquo;charge&rdquo; est levé.</p>
<p>Notez qu&rsquo;il n&rsquo;y a jamais d&rsquo;erreur &ldquo;Invalid Syntax&rdquo; sur une page 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































.
Les navigateurs corrigent tout contenu invalide et l&rsquo;envoie.</p>
<h3 id="interprétation-du-css">Interprétation du CSS</h3>
<ul>
<li>
<p>Analyse des fichiers 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, du contenu des balises <code>&lt;style&gt;</code>,
et des valeurs des attributs <code>style</code> en utilisant la
&ldquo;<a href="http://www.w3.org/TR/CSS2/grammar.html" rel="external">syntaxe de grammaire et champ lexical 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































</a>&rdquo;.</p>
</li>
<li>
<p>Chaque fichier 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































 est analysé dans un <code>StyleSheet object</code>,
où chaque objet contient les règles 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































 avec les sélecteur et
les objets correspondant à la grammaire 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































.</p>
</li>
<li>
<p>Un analyseur 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































 peut être descendant ou ascendant lorsqu&rsquo;un
générateur d&rsquo;analyse spécifique est utilisé.</p>
</li>
</ul>
<h3 id="rendu-de-page">Rendu de Page</h3>
<ul>
<li>
<p>Crée une &ldquo;Arborescence d&rsquo;Image&rdquo; ou une &lsquo;Arborescence de Rendu&rdquo; en traversant
les nœuds du 



















<abbr lang="en" title="Document Object Model">DOM</abbr>




























































































, et en calculant les valeurs du style

  
  
  
  
  
  
  
  
  
  
  
  <abbr lang="en" title="Cascade Style Sheet">CSS</abbr>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 pour chaque nœud.</p>
</li>
<li>
<p>Calcul la largeur préférée de chaque nœud de l&rsquo;arbre du cadre de bas
en haut en additionnant la largeur préférée des nœuds enfants et les
marges horizontales, les bordures et le padding du nœud.</p>
</li>
<li>
<p>Calcul la largeur actuelle de chaque nœud de haut en bas en allouant à
chaque nœud disponible la largeur de ses enfants.</p>
</li>
<li>
<p>Calcul la hauteur de chaque nœud de bas en haut en appliquant un habillage
de texte et en additionnant les hauteurs des nœuds enfants, les marges,
les bordures et le padding du nœud.</p>
</li>
<li>
<p>Calcul les coordonnées de chaque nœud en utilisant l&rsquo;information calculée
ci-dessus.</p>
</li>
<li>
<p>Des étapes plus compliquées sont menées lorsque les éléments sont positionnés
en <code>floated</code>, <code>absolutely</code> ou <code>relatively</code>, ou lorsque d&rsquo;autres
fonctionnalités plus complexes sont utilisées. Pour avoir plus de détails,
voir <a href="http://dev.w3.org/csswg/css2/" rel="external">http://dev.w3.org/csswg/css2/</a> et <a href="http://www.w3.org/Style/CSS/current-work" rel="external">http://www.w3.org/Style/CSS/current-work</a></p>
</li>
<li>
<p>Crée des calques pour décrire quelles parties de la page peuvent être
animées en tant que groupe sans être re-traitées. Chaque objet d&rsquo;image
ou de rendu peut être assigné à un calque.</p>
</li>
<li>
<p>Des textures sont allouées à chaque calque de la page.</p>
</li>
<li>
<p>Les objets d&rsquo;image ou de rendu pour chaque calque sont parcourus et des
commandes de dessein sont exécutées pour leur calque respectif. Ils doivent
être traités par le 










<abbr lang="en" title="Central Processing Unit">CPU</abbr>





































































































 ou dessinés par le 




























<abbr lang="en" title="Graphic Processing Unit">GPU</abbr>




















































































en utilisant directement D2D/SkiaGL.</p>
</li>
<li>
<p>Toutes les étapes ci-dessus peuvent réutilisées les valeurs calculées
depuis la dernière fois où la page web a été rendue, ainsi les changements
incrémentaux demandent moins de travail.</p>
</li>
<li>
<p>Les calques de page sont envoyés au processus de composition où ils sont
combinés avec les calques d&rsquo;autres contenus visibles, tel que le chrome
du navigateur, les iframes, et les panneaux d&rsquo;extension.</p>
</li>
<li>
<p>Les positions de calque final sont calculés et les commandes de composition
sont émises via Direct3D/OpenGL. Les tampons de commande du 




























<abbr lang="en" title="Graphic Processing Unit">GPU</abbr>




















































































sont vidés vers le 




























<abbr lang="en" title="Graphic Processing Unit">GPU</abbr>



















































































 pour le rendu asynchrone et l&rsquo;image est
envoyée au serveur de fenêtrage.</p>
</li>
</ul>
<h3 id="rendu-du-gpu">Rendu du GPU</h3>
<ul>
<li>
<p>Durant le processus de rendu, les calques de calcul graphique peuvent
utilisés aussi bien le <code>CPU</code> que le processeur graphique <code>GPU</code>.</p>
</li>
<li>
<p>Lors de l&rsquo;utilisation du <code>GPU</code> pour le calcul du rendu graphique, les
calques du logiciel graphique découpe la tâche en de multiples pièces,
ainsi il peut utiliser avantageusement le parallélisme massif du <code>GPU</code>
pour le calcul de virgule flottante requis pour le processus de rendu.</p>
</li>
</ul>
<h3 id="exécution-post-rendu-et-induite-par-lutilisateur">Exécution Post-Rendu et induite par l&rsquo;utilisateur</h3>
<p>Après que le rendu soit complet, le navigateur exécute le code JavaScript
grâce à un mécanisme de temporisation <em>(tel qu&rsquo;une animation Google Doodle)</em>
ou à une interaction de l&rsquo;utilisateur <em>(écrivant une requête dans une boîte
de recherche et recevant des suggestions)</em>.</p>
<p>Des plugins tels que Flash ou Java peuvent aussi être exécutés, mais actuellement
pas depuis la page d&rsquo;accueil de Google. Des scripts peuvent causer des
requêtes réseaux additionnelles, modifier la page ou sa mise en page,
entraînant un nouveau cycle de rendu et de dessin de la page.</p>
<h2 id="épilogue">Épilogue</h2>
<p>Les <a href="https://github.com/hucste/what-happens-when/blob/master/README-fr.rst" rel="external">sources &ldquo;officielles&rdquo; de la traduction de cet article sont disponibles
sur mon espace de dépôt GitHub</a>. Si vous voyez des erreurs de traduction,
de sens, si en tant qu&rsquo;experts/utilisateurs confirmés, vous souhaitez apporter
des précisions/corrections, n&rsquo;hésitez pas à <a href="https://github.com/hucste/what-happens-when/issues" rel="external">lever une issue</a>, voire mieux
à <a href="https://github.com/hucste/what-happens-when/pulls" rel="external">fournir une PR</a> ;-)</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN→FR : Que se passe-t-il quand vous écrivez dans la barre d&#39;adresse du navigateur web ?!]]></summary>
        <published>2020-09-16T21:19:47+02:00</published>
        <updated>2025-11-18T16:07:44+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d1df3eef-003e-dafe-be6b-f39abaf68cbd</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/sysupgrade/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="sysupgrade" scheme="http://doc.huc.fr.eu.org/fr/tags/sysupgrade/" />
        <category term="opkg" scheme="http://doc.huc.fr.eu.org/fr/tags/opkg/" />
        <category term="sysadmin" scheme="http://doc.huc.fr.eu.org/fr/tags/sysadmin/" />
        <category term="router" scheme="http://doc.huc.fr.eu.org/fr/tags/router/" />
        <category term="Ubiquiti" scheme="http://doc.huc.fr.eu.org/fr/tags/ubiquiti/" />
        <category term="EdgeRouter" scheme="http://doc.huc.fr.eu.org/fr/tags/edgerouter/" />
        <category term="Xiaomi" scheme="http://doc.huc.fr.eu.org/fr/tags/xiaomi/" />
        <category term="Mi" scheme="http://doc.huc.fr.eu.org/fr/tags/mi/" />
        <category term="Redmi" scheme="http://doc.huc.fr.eu.org/fr/tags/redmi/" />
        <category term="AC2100" scheme="http://doc.huc.fr.eu.org/fr/tags/ac2100/" />
        <category term="AX3000T" scheme="http://doc.huc.fr.eu.org/fr/tags/ax3000t/" />
        <category term="One" scheme="http://doc.huc.fr.eu.org/fr/tags/one/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Avant de faire la mise à jour du système, veuillez IMPÉRATIVEMENT bien lire
l&rsquo;annonce de version faite par le projet OpenWRT, et tout particulièrement les
chapitres &ldquo;Upgrading to…&rdquo; et &ldquo;Known issues&rdquo;. En effet ces chapitres peuvent
contenir des informations relatives à votre routeur ; faire l&rsquo;impasse pourrait
endommager votre matériel et le rendre inutilisable !</div>

<p>OpenWRT a un outil pour faire la mise à niveau d&rsquo;une version à une autre
nommé <strong>sysupgrade</strong>. Il est possible de l&rsquo;invoquer depuis l&rsquo;interface web
d&rsquo;administration LuCI.</p>
<p>Si le procédé vous intéresse plus que le faire par CLI, lisez la note en
question : <a href="/fr/sys/openwrt/sysupgrade/#flash-depuis-luci">Flash depuis LuCI</a></p>
<hr>
<p>Le procédé suivant explique pas-à-pas la mise à niveau tout en mode CLI,
tout en préservant la configuration utilisateur…</p>
<h2 id="procédé">Procédé</h2>
<p>La première chose à laquelle nous veillons est d&rsquo;installer l&rsquo;outil <code>curl</code>,
car par défaut le binaire <code>wget</code> nativement installé ne supporte pas TLS.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# opkg install curl
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### opkgscript.sh</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Le script <span style="color:#48b685">`</span>opkgscript.sh<span style="color:#48b685">`</span> permet de sauvegarder la liste des paquets
</span></span><span style="display:flex;"><span>installés en sus de la base.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>⇒ Récupèrons le depuis <span style="color:#5bc4bf">[</span>opkgscript.sh<span style="color:#5bc4bf">](</span>https://raw.githubusercontent.com/richb-hanover/OpenWrtScripts/master/opkgscript.sh<span style="color:#5bc4bf">)</span> :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:$ curl -O https://raw.githubusercontent.com/richb-hanover/OpenWrtScripts/master/opkgscript.sh<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;!--
</span></span><span style="display:flex;"><span>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Au cas où, je mets à disposition le <a href="/share/opkgscript">script</a>…</div>

</span></span><span style="display:flex;"><span>--&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>⇒ Donnons les droits d<span style="color:#48b685">&#39;exécution nécessaire :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# chmod 0700 opkgscript.sh`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">&lt;!--
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Copier le localement sur votre machine d&rsquo;administration… surtout qu&rsquo;après la
mise à niveau, il pourrait être possible que vous n&rsquo;ayez plus momentanément
Internet, sauf normalement depuis le routeur.</div>

</span></span></span><span style="display:flex;"><span><span style="color:#48b685">--&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ Sauvegardons la liste des paquets installés - *pour pouvoir restaurer
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">après la mise à niveau système* :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```sh
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">:# ./opkgscript.sh -v write
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Le script écrit la liste dans un fichier `/etc/config/opkg.installed`.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### Téléchargement firmware
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Depuis le répertoire `/tmp`, récupèrons la nouvelle version du firmware :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">- e.g. pour la version actuelle :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# v=&#34;24.10.5&#34;`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ pour le routeur **OpenWRT One** :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# curl -O https://downloads.openwrt.org/releases/&#34;${v}&#34;/targets/mediatek/filogic/{openwrt-&#34;${v}&#34;-mediatek-filogic-openwrt_one-squashfs-sysupgrade.itb,sha256sums}`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ pour le routeur **Ubiquiti EdgeRouter X** :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# curl -O https://downloads.openwrt.org/releases/&#34;${v}&#34;/targets/ramips/mt7621/{openwrt-&#34;${v}&#34;-ramips-mt7621-ubnt_edgerouter-x-squashfs-sysupgrade.bin,sha256sums}`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ pour le **Xiaomi Mi Router AX3000T** :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# curl -O https://downloads.openwrt.org/releases/&#34;${v}&#34;/targets/mediatek/filogic/{openwrt-&#34;${v}&#34;-mediatek-filogic-xiaomi_mi-router-ax3000t-squashfs-sysupgrade.bin,sha256sums}`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ pour le **Xiaomi Redmi Router AC2100** :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# curl -O https://downloads.openwrt.org/releases/&#34;${v}&#34;/targets/ramips/mt7621/{openwrt-&#34;${v}&#34;-ramips-mt7621-xiaomi_redmi-router-ac2100-squashfs-sysupgrade.bin,sha256sums}`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">#### Vérification du téléchargement
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Puis, nous vérifions la somme de contrôle afin de nous assurer du firmware :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```sh
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">:$ sha256sum -c sha256sums 2&gt; /dev/null | grep OK
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ Résultat correct pour le routeur **OpenWRT One** : \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`openwrt-24.10.4-mediatek-filogic-openwrt_one-squashfs-sysupgrade.itb: OK`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p><strong>ATTENTION</strong> : Si la vérification échoue, allez en discuter sur le forum !</p>
<p><strong>Ne cherchez pas à mettre à jour avec un micro-logiciel corrompu !!!</strong></p>
</div>

</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### Sauvegarde configuration
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">L&#39;</span>étape suivante est de vérifier la configuration de la sauvegarde :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>:# sysupgrade -l
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Si nécessaire, il faut éditer le fichier pour ajouter certains répertoires/fichiers,
</span></span><span style="display:flex;"><span>ainsi dans le cas où un <a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">utilisateur a été ajouté correctement au groupe `sudo`</a>
,
</span></span><span style="display:flex;"><span>il faudra ajouter ce qui suit dans le fichier <span style="color:#48b685">`</span>/etc/sysupgrade.conf<span style="color:#48b685">`</span> :
</span></span><span style="display:flex;"><span>* /etc/sudoers
</span></span><span style="display:flex;"><span>* /etc/sudoers.d/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Vérifions à nouveau - et sauvegardons la configuration :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>:# sysupgrade -b /tmp/backup-<span style="color:#f99b15">${</span><span style="color:#ef6155">HOSTNAME</span><span style="color:#f99b15">}</span>-<span style="color:#815ba4">$(</span>date +%F<span style="color:#815ba4">)</span>.tar.gz
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">On peut remarquer que dans la sauvegarde en question se trouve le fichier
<code>/etc/config/opkg.installed</code> précédemment créé avec le script <code>opkgscript.sh</code>.</div>

</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Puis, il faut récupèrer cette sauvegarde :
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:$ scp root@openwrt:/tmp/backup*.tar.gz <span style="color:#815ba4">$(</span>pwd<span style="color:#815ba4">)</span><span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>*<span style="color:#5bc4bf">(</span>où <span style="color:#48b685">&#39;openwrt&#39;</span> est l<span style="color:#48b685">&#39;adresse IP de votre routeur…)*
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Si vous avez le message d&rsquo;erreur suivant :
<code>ash: /usr/libexec/sftp-server: not found</code></p>
<p>Merci de lire la note ci-dessous <a href="/fr/sys/openwrt/sysupgrade/#à-propos-de-ssh-v90-et-supérieure">À-propos de SSH v9.0 et supérieure</a></p>
<hr>
<p>La note <a href="/fr/sys/openwrt/sysupgrade/#libération-mémoire">À-propos de la libération de la mémoire</a>
peut-être intéressante à lire, mais peu utile dans le contexte des routeurs mis
en exemple, car dans leur cas, une RAM conséquente est embarquée.</p>
</div>

</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### Mise à Niveau Système
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Passons à la mise à niveau système, tel que, par exemple :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# sysupgrade -v openwrt-&#34;${v}&#34;-*-sysupgrade.bin` ou \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# sysupgrade -v openwrt-&#34;${v}&#34;-*-sysupgrade.itb` selon le modèle de routeur.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ Exemple, pour le routeur **OpenWRT One** :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```ash
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">:# sysupgrade -v openwrt-&#34;$v&#34;-mediatek-filogic-openwrt_one-squashfs-sysupgrade.itb
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">(date) upgrade: Saving config files...
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/attendedsysupgrade
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/dhcp
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/dropbear
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/firewall
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/https-dns-proxy
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/luci
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/network
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/opkg.installed
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/rpcd
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/system
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/ubihealthd
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/ubootenv
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/uhttpd
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/unbound
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/wifi_schedule
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/config/wireless
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/crontabs/root
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/dropbear/authorized_keys
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/dropbear/dropbear_ed25519_host_key
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/dropbear/dropbear_rsa_host_key
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/fw_env.config
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/group
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/hosts
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/inittab
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/luci-uploads/.placeholder
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/nftables.d/10-custom-filter-chains.nft
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/nftables.d/README
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/opkg/keys/8a11255d14aef6c8
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/opkg/keys/d310c6f2833e97f7
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/passwd
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/profile
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/profile.d/busybox-history-file.sh
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/rc.local
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/shadow
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/shells
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/shinit
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/sysctl.conf
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/sysupgrade.conf
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/uhttpd.crt
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/uhttpd.key
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/unbound/unbound.conf
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">etc/unbound/unbound_ext.conf
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">root/opkgscript.sh
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">(date) upgrade: Commencing upgrade. Closing all shell sessions.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Normalement votre session SSH va se fermer et le routeur démarrer !
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Lors de la reconnexion au routeur depuis votre client SSH, il peut
arriver que la connexion soit empêchée avec le message d&rsquo;erreur suivant :</p>
<p><code>WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED</code>.
Si c&rsquo;est le cas, merci de lire la note adéquate :
<a href="/fr/sys/openwrt/sysupgrade/#à-propos-de-lidentification-de-lhôte-à-distance-par-ssh">À-propos de l&rsquo;identification de l&rsquo;hôte à distance par SSH</a></p>
<hr>
<p>Si jamais vous faites une migration depuis 19.07.x vers 21.02.x ou
supérieure, veuillez lire impérativement la note ad hoc :
<a href="/fr/sys/openwrt/sysupgrade/#à-propos-de-la-migration-vers--21020">À-propos de la Migration vers ≥ 21.02.0</a></p>
<hr>
<p>Après le reboot, il peut arriver que le routeur n&rsquo;ait plus accès à Internet.
Merci de vérifier le fichier <code>/etc/resolv.conf</code> et de le reconfigurer si
besoin.</p>
</div>

</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">#### Vérification nouvelle version
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">À partir du moment où vous pourrez vous connecter à nouveau à votre routeur,
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">vous retrouverez l&#39;</span>information relative à votre nouvelle version :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>- depuis LuCI, aller vers <span style="color:#48b685">&#34;Status&#34;</span> &gt; <span style="color:#48b685">&#34;Overview&#34;</span>, celui-ci sera affiché
</span></span><span style="display:flex;"><span>    dans la section <span style="color:#48b685">&#34;System&#34;</span>, face à l<span style="color:#48b685">&#39;information &#34;Firmware version&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">- en SSH, dans la bannière de connexion affichant ce nouveau numéro de
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    version, comme ci-dessous :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```ash
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">BusyBox v1.36.1 (2025-12-17 21:08:22 UTC) built-in shell (ash)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  _______                     ________        __
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> |       |.-----.-----.-----.|  |  |  |.----.|  |_
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> |_______||   __|_____|__|__||________||__|  |____|
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">          |__| W I R E L E S S   F R E E D O M
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> -----------------------------------------------------
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> OpenWrt 24.10.5, r29087-d9c5716d1d
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> -----------------------------------------------------
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### Mise à Niveau &#34;tiers&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Sur les routeurs ayant moins de 4 Mo de NVRAM, les mises à jour peuvent
ne pas avoir lieu correctement ; il est nécessaire de s&rsquo;assurer d&rsquo;avoir
au moins 600 Ko de libre.</p>
<p>Essayez de <a href="/fr/sys/openwrt/sysupgrade/#libération-mémoire">libérer de la mémoire</a>…</p>
<p>Vérifiez les caractéristiques techniques de votre routeur !</p>
</div>

</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ Effectuons la mise à niveau des paquets tiers :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">`:# opkg update &amp;&amp; opkg list-upgradable`
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Normalement suite à la mise à niveau, il ne devrait pas y en avoir.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">S&#39;</span>il y en a, exécutez la commande suivante :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>:# <span style="color:#815ba4">for</span> name in <span style="color:#48b685">`</span>opkg list-upgradable | awk <span style="color:#48b685">&#39;{print $1}&#39;</span><span style="color:#48b685">`</span>; <span style="color:#815ba4">do</span> opkg upgrade <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### Restauration profil utilisateur</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Pour restaurer le profil utilisateur, on répète les étapes d<span style="color:#48b685">&#39;installation
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">de l&#39;</span>outil curl, puis du script <span style="color:#48b685">`</span>opkgscript.sh<span style="color:#48b685">`</span>.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Et une fois installé et les droits d<span style="color:#48b685">&#39;exécution attribués, on l&#39;</span>exécute pour
</span></span><span style="display:flex;"><span>qu<span style="color:#48b685">&#39;il complète l&#39;</span>installation du <span style="color:#48b685">&#34;profil utilisateur&#34;</span> :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>:# ./opkgscript.sh -v install
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Pour finir, mieux vaut redémarrer !
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## Ultimes Vérifications</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Ensuite, vérifier la configuration de votre routeur :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>* que vos différentes interfaces réseaux soient toujours présentes et
</span></span><span style="display:flex;"><span>    opérationnelles.
</span></span><span style="display:flex;"><span>* que votre configuration <span style="color:#48b685">&#34;firewall&#34;</span> soit correcte ; vérifiez dans les
</span></span><span style="display:flex;"><span>    différents onglets votre configuration.
</span></span><span style="display:flex;"><span>* que les différents services, que vous auriez précédement installés,
</span></span><span style="display:flex;"><span>    soient toujours opérationnels, tel qu<span style="color:#48b685">&#39;un tunnel 





































<span lang="en">IPv6 <em>(Internet Protocol v6)</em></span>









































































, OpenVPN,
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ou tout service accessible depuis le menu &#34;Services&#34;.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Voilà…
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Normalement, tout devrait fonctionner correctement en suivant
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">ce processus de mise à niveau.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">## Notes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Retrouvez ci-dessous différentes notes d&#39;</span>informations utiles, seulement
</span></span><span style="display:flex;"><span>dans certains contextes.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### Flash depuis LuCI</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Depuis le menu <span style="color:#48b685">&#34;System&#34;</span> &gt; <span style="color:#48b685">&#34;Backup / Flash firmware&#34;</span> de l<span style="color:#48b685">&#39;interface web LuCI :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">1/ Il est utile d&#39;</span>aller à l<span style="color:#48b685">&#39;onglet &#39;</span>Configuration<span style="color:#48b685">&#39; pour modifier la liste
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">des fichiers personnalisés à sauvegarder aussi… \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Si les fichiers et autres répertoires relatifs à l&#39;</span>installation de binaires
</span></span><span style="display:flex;"><span>tiers ne sont pas écrits ici, rien ne sera sauvegardé !
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>2/ Faites une sauvegarde de votre configuration d<span style="color:#48b685">&#39;OpenWRT depuis l&#39;</span>onglet
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Actions&#39;</span>, section <span style="color:#48b685">&#39;Backup&#39;</span>.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>3/ Lors du processus pour flasher une nouvelle image de mise à niveau :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>⇒ Pensez à utiliser les options :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>- la <span style="color:#815ba4">case</span> à cocher **KEEP SETTINGS AND RETAIN THE CURRENT CONFIGURATION**,
</span></span><span style="display:flex;"><span>    à minima
</span></span><span style="display:flex;"><span>- la <span style="color:#815ba4">case</span> à cocher **INCLUDE IN BACKUP A LIST OF CURRENT INSTALLED PACKAGES AT /ETC/BACKUP/INSTALLED_PACKAGES.TXT**,
</span></span><span style="display:flex;"><span>    qui inclut une liste des paquets supplémentaires installés par vos soins.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Si ces cases ne sont pas cochées, vous perdrez toute votre configuration
</span></span><span style="display:flex;"><span>lié à OpenWRT.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>De même les binaires tiers seront dans tous les cas à réinstaller, voire
</span></span><span style="display:flex;"><span>à reconfigurer.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Gardez à l<span style="color:#48b685">&#39;esprit QUE des changements induits par les mises à niveau vers
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">une version majeure peuvent poser des soucis lors de la migration. Il peut
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">y avoir des changements critiques.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### À-propos de SSH v9.0 et supérieure
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Si votre client SSH est de version ≥ 9.0 :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">À partir de la version 9.0 de SSH, le comportement de `scp` a changé. \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Dans l&#39;</span>état, la commande ci-dessus échouera avec le message d<span style="color:#48b685">&#39;erreur suivant :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">scp router:/tmp/backup-***-2022-04-21.tar.gz .
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">ash: /usr/libexec/sftp-server: not found
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">scp: Connection closed
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Dans les faits, Dropbear ne peut plus discuter avec…
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Ajoutez l&#39;</span>option <span style="color:#48b685">`</span>-O<span style="color:#48b685">`</span> à la commande <span style="color:#48b685">`</span>scp<span style="color:#48b685">`</span>, tel que :
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:$ scp -O root@openwrt:/tmp/backup*.tar.gz <span style="color:#815ba4">$(</span>pwd<span style="color:#815ba4">)</span><span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>*<span style="color:#5bc4bf">(</span>cela rétablit l<span style="color:#48b685">&#39;ancien comportement SFTP de scp)*
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Une autre astuce est d&#39;</span><a class="inside" href="/fr/sys/openwrt/openssh/" title="Lien interne vers l&#39;article : 'OpenWRT : OpenSSH pour remplacer Dropbear'">installer le serveur OpenSSH en lieu et place de Dropbear</a>
.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### Libération mémoire</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Cette section est surtout utile si le système de fichier <span style="color:#48b685">`</span>/tmp<span style="color:#48b685">`</span> n<span style="color:#48b685">&#39;est pas
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">assez grand pour enregistrer l&#39;</span>image d<span style="color:#48b685">&#39;OpenWRT. Les actions ci-dessous
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">vont permettre de libérer temporairement de l&#39;</span>espace dans la RAM.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Par acquis de conscience, assurons-nous de l<span style="color:#48b685">&#39;espace mémoire et disque
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">avec les commandes `free` et `df`, voire `cat /proc/meminfo` ; le but
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">est de vérifier que **la taille de RAM *libre* est plus importante que la
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">taille de l&#39;</span>image** téléchargée. Si c<span style="color:#48b685">&#39;est le cas, nous pouvons continuer
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">le processus, sinon, nous avons un sérieux problème et il faut en discuter
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">sur le forum d&#39;</span>OpenWRT.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Prenons un exemple pour mieux comprendre :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>⇒ la taille du binaire d<span style="color:#48b685">&#39;upgrade de la version ci-dessus :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```ash
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">:$ ll -h
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">(…)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">-rw-rw-r-- 1 root root 6.7M Sep  10 13:53 openwrt-22.03.0-ramips-mt7621-xiaomi_redmi-router-ac2100-squashfs-sysupgrade.bin
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">(…)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">elle est donc de 6.7 Mo.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">⇒ L&#39;</span>espace disponible dans <span style="color:#48b685">`</span>/tmp<span style="color:#48b685">`</span> :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>ash
</span></span><span style="display:flex;"><span>:# df -h
</span></span><span style="display:flex;"><span>Filesystem                Size      Used Available Use% Mounted on
</span></span><span style="display:flex;"><span>/dev/root                 3.8M      3.8M         <span style="color:#f99b15">0</span> 100% /rom
</span></span><span style="display:flex;"><span>tmpfs                    59.7M    540.0K     59.1M   1% /tmp
</span></span><span style="display:flex;"><span>/dev/ubi0_1              97.2M      7.8M     84.7M   8% /overlay
</span></span><span style="display:flex;"><span>overlayfs:/overlay       97.2M      7.8M     84.7M   8% /
</span></span><span style="display:flex;"><span>tmpfs                   512.0K         <span style="color:#f99b15">0</span>    512.0K   0% /dev
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>Dans le contexte du Xiaomi Redmi AC2100, à ce jour, l<span style="color:#48b685">&#39;espace disponible
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">est de 59.1 Mo, ce qui est largement suffisant pour récupèrer l&#39;</span>image
</span></span><span style="display:flex;"><span>de mise à niveau et la gérer.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>⇒ De même, l<span style="color:#48b685">&#39;espace libérée de mémoire :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```ash
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">:# free -m
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">              total        used        free      shared  buff/cache   available
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Mem:         122220       40532       61400         540       20288       46700
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Swap:             0           0           0
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">```
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Dans ce contexte, l&#39;</span>espace libre en mémoire est de d<span style="color:#48b685">&#39;environ 60 Mo. Là,
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">encore, il y a assez d&#39;</span>espace pour gérer l<span style="color:#48b685">&#39;image de mise à niveau.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">**Si** ainsi, dans votre contexte, l&#39;</span>espace totale disponible, soit celle de
</span></span><span style="display:flex;"><span>la mémoire plus celle en <span style="color:#48b685">`</span>/tmp<span style="color:#48b685">`</span> n<span style="color:#48b685">&#39;est pas assez grande, il est possible
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">d&#39;</span>essayer ce qui suit - supprimer ce qui devient désormais inutile :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>* les fichiers de listes des paquets :
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:# rm -r /tmp/opkg-lists/<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>* les caches suivants :
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:# sync <span style="color:#5bc4bf">&amp;&amp;</span> echo <span style="color:#f99b15">3</span> &gt; /proc/sys/vm/drop_caches<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>* Et si nécessaire, suppression des pilotes wifi suivants :
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>:# rm /etc/modules.d/*<span style="color:#5bc4bf">{</span>80211,ath9k,b43<span style="color:#5bc4bf">}</span>*<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span>* Pour finir, vérifiez qu<span style="color:#48b685">&#39;il n&#39;</span>y ait aucun lien symbolique dans le répertoire
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">`</span>/etc/modules.d<span style="color:#48b685">`</span>, si c<span style="color:#48b685">&#39;est le cas, détruisez-les, ce qui libérera de
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    la RAM au prochain démarrage, puis **redémarrez absolument OpenWRT**
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    avant de faire la mise à niveau.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">---
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">### À-propos de l&#39;</span>identification de l<span style="color:#48b685">&#39;hôte à distance par SSH
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Lors de la nouvelle connexion par SSH, il est normalement possible que
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">vous ayez le droit au message d&#39;</span>erreur suivant :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
</span></span><span style="display:flex;"><span>@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
</span></span><span style="display:flex;"><span>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
</span></span><span style="display:flex;"><span>IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
</span></span><span style="display:flex;"><span>Someone could be eavesdropping on you right now <span style="color:#5bc4bf">(</span>man-in-the-middle attack<span style="color:#5bc4bf">)</span>!
</span></span><span style="display:flex;"><span>It is also possible that a host key has just been changed.
</span></span><span style="display:flex;"><span>The fingerprint <span style="color:#815ba4">for</span> the ED25519 key sent by the remote host is
</span></span><span style="display:flex;"><span>SHA256:0atP7BnQQ98EVJciOCBDYAUD245lKm2tbau8BgWMpQ0.
</span></span><span style="display:flex;"><span>Please contact your system administrator.
</span></span><span style="display:flex;"><span>Add correct host key in /home/you/.ssh/known_hosts to get rid of this message.
</span></span><span style="display:flex;"><span>Offending RSA key in /home/you/.ssh/known_hosts:93
</span></span><span style="display:flex;"><span>  remove with:
</span></span><span style="display:flex;"><span>  ssh-keygen -f <span style="color:#48b685">&#34;/home/you/.ssh/known_hosts&#34;</span> -R <span style="color:#48b685">&#34;192.168.xyz.1&#34;</span>
</span></span><span style="display:flex;"><span>ED25519 host key <span style="color:#815ba4">for</span> 192.168.xyz.1 has changed and you have requested strict checking.
</span></span><span style="display:flex;"><span>Host key verification failed.
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>**Ne paniquez pas, c<span style="color:#48b685">&#39;est normal !**
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Ayant changé de version de système d&#39;</span>exploitation, l<span style="color:#48b685">&#39;identification de l&#39;</span>hôte
</span></span><span style="display:flex;"><span>a changé aussi.
</span></span><span style="display:flex;"><span>Appliquez la commande ssh-keygen, telle que donnée, dans votre cas, pour
</span></span><span style="display:flex;"><span>supprimer l<span style="color:#48b685">&#39;ancienne identification d&#39;</span>hôte. Puis retentez votre connexion.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Après la mise à niveau, il est très probable que les machines derrière le
routeur n&rsquo;aient plus accès correctement à Internet. <br>
C&rsquo;est une phase normale ; ne pas paniquer !</p>
<p>En effet, ne pas oublier que <code>sysupgrade</code> supprime toute configuration utilisateur.
L&rsquo;étape suivante va d&rsquo;être de restaurer le &ldquo;profil utilisateur&rdquo;.</p>
</div>

</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### À-propos de la Migration vers ≥ 21.02.0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Prérequis matériel minimum</strong> : À partir de la version 21.02.0, le minimum
requis est de 8 Mo de flash, et 64 Mo de RAM.</div>

</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Vous avez choisi de migrer vers la version 21.02.0-*** depuis 19.07.***,
</span></span><span style="display:flex;"><span>c<span style="color:#48b685">&#39;est bien !
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Mais avant de faire toute autre action, connectez-vous à l&#39;</span>interface web,
</span></span><span style="display:flex;"><span>puis sur le menu <span style="color:#48b685">&#34;Interfaces&#34;</span> ; il va vous être proposé de faire une
</span></span><span style="display:flex;"><span>migration de la configuration, faites-la !
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Puis, redémarrez !
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### resolv.conf</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>À ce moment de l<span style="color:#48b685">&#39;étape, il est possible que vous ne puissiez plus
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">communiquer avec l&#39;</span>extérieur, car le fichier <span style="color:#48b685">`</span>/etc/resolv.conf<span style="color:#48b685">`</span> est
</span></span><span style="display:flex;"><span>toujours configuré pour la résolution de noms en interne, tel que :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>cfg
</span></span><span style="display:flex;"><span>:# cat /etc/resolv.conf
</span></span><span style="display:flex;"><span>search huc.home
</span></span><span style="display:flex;"><span>nameserver 127.0.0.1
</span></span><span style="display:flex;"><span>nameserver ::1
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Dans ce cas, éditez le fichier pour ajouter un serveur DNS à interroger,
</span></span><span style="display:flex;"><span>tel que ceux de la FDN : <span style="color:#48b685">`</span>80.67.169.12<span style="color:#48b685">`</span>, et <span style="color:#48b685">`</span>2001:910:800::12<span style="color:#48b685">`</span>.
</span></span><span style="display:flex;"><span>Par exemple :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>sh
</span></span><span style="display:flex;"><span>:# sed -i -e <span style="color:#48b685">&#39;s/127.0.0.1/80.67.169.12/;s/::1/2001:910:800::12/&#39;</span> /etc/resolv.conf
</span></span><span style="display:flex;"><span><span style="color:#48b685">```</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Bien sûr, modifiez à votre convenance !
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;!--
</span></span><span style="display:flex;"><span>Exemple : 8.8.8.8 ! <span style="color:#776e71"># Cx de Google !</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sed -i -e <span style="color:#48b685">&#39;s/127.0.0.1/8.8.8.8/;s/::1//&#39;</span> /etc/resolv.conf
</span></span><span style="display:flex;"><span>sed -i -e <span style="color:#48b685">&#39;s/80.67.169.12/8.8.8.8/;s/2001:910:800::12//&#39;</span> /etc/resolv.conf
</span></span><span style="display:flex;"><span>--&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## Documentations</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Comme vous pourrez le lire dans la documentation du wiki OpenWRT, il y a
</span></span><span style="display:flex;"><span>d<span style="color:#ef6155">&#39;</span>autres méthodes ; celle que je vous propose me semble la plus pertinente…
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>- <span style="color:#5bc4bf">[</span>Upgrading OpenWrt firmware using LuCI and CLI<span style="color:#5bc4bf">](</span>https://openwrt.org/docs/guide-user/installation/generic.sysupgrade<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>- <span style="color:#5bc4bf">[</span>Upgrading OpenWrt firmware using LuCI<span style="color:#5bc4bf">](</span>https://openwrt.org/docs/guide-quick-start/sysupgrade.luci<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>- <span style="color:#5bc4bf">[</span>Upgrading OpenWrt firmware using CLI<span style="color:#5bc4bf">](</span>https://openwrt.org/docs/guide-user/installation/sysupgrade.cli<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---
</span></span></code></pre></div>]]></content>
        <summary type="html"><![CDATA[Comment mettre à niveau correctement OpenWRT… sans perdre de données de configuration utilisateur (&#43;) explications pour la migration vers une version majeure ; routeurs servis comme exemple : OpenWRT One, Ubiquiti EdgeRouter X, Xiaomi Redmi AC2100, Xiaomi Mi Router AX3000T]]></summary>
        <published>2020-09-14T18:03:35+02:00</published>
        <updated>2025-12-22T13:43:32+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:922551ea-9661-b87a-48a2-12e929b3561c</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/bsdhowto.ch/malware/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Comment construire un serveur de scan de malware</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="malware" scheme="http://doc.huc.fr.eu.org/fr/tags/malware/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://www.bsdhowto.ch/malware.html" rel="external">How to build a malware scan server</a></strong>&rdquo;,
écrit par Bruno Flückiger.</p>
<hr>
<p>Date : 2020-05-16</p>
<h2 id="introduction">Introduction</h2>
<p>Récemment, j&rsquo;ai eu la tâche de construire, au travail, un serveur de
scan de malware supportant <a href="https://tools.ietf.org/html/rfc3507" rel="external">ICAP</a>.
Actuellement, nous utilisons RedHat Enterprise Linux. Mais
<a href="http://c-icap.sourceforge.net/" rel="external">c-icap</a> n&rsquo;est pas disponible en tant
que paquet dans un des dépôts de confiance, alors j&rsquo;ai décidé d&rsquo;utiliser
<a href="https://www.openbsd.org/" rel="external">OpenBSD</a> pour cette tâche.</p>
<p>Le serveur de scan de malware utilise <a href="https://www.clamav.net/" rel="external">ClamAV</a>
en tant que scanner de malware et c-icap en tant que serveur ICAP,
fournissant une interface pour chaque produit qui supporte ICAP tel
<a href="http://www.squid-cache.org/" rel="external">Squid</a>.</p>
<h2 id="installation-des-paquets">Installation des paquets</h2>
<p>C&rsquo;est une tâche très simple, un seul paquet s&rsquo;occupe de tout :
<code>$ doas pkg_add -i c-icap-clamav</code></p>
<p>Ce paquet contient le module c-icap pour ClamAV qui installe c-icap et
clamav en dépendances.</p>
<h2 id="configuration-de-clamav">Configuration de ClamAV</h2>
<p>Deux des trois démons installés par ClamAv sont d&rsquo;intérêt : freshclam et
clamd. En premier, configurez freshclam afin de vous assurer que la base
de données des malware de ClamAV reste à jour.</p>
<p>Le fichier <code>/etc/freshclam.conf</code> contient les paramètres suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">LogTime yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LogSyslog yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LogFacility LOG_DAEMON</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DatabaseMirror db.ch.clamav.net</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DatabaseMirror database.clamav.net</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">NotifyClamd /etc/clamd.conf</span>
</span></span></code></pre></div><p>Maintenant, activez et démarrez freshclam afin qu&rsquo;il mette à jour la
signature de la base de donnée de ClamAV :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas rcctl enable freshclam
</span></span><span style="display:flex;"><span>$ doas rcctl start freshclam
</span></span></code></pre></div><p>Ensuite, configurez clamd. Dans le fichier <code>/etc/clamd.conf</code>, les lignes
suivantes sont paramétrées :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">LogTime yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LogSyslog yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LogFacility LOG_DAEMON</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">TemporaryDirectory /tmp</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LocalSocket /var/clamav/clamd.sock</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">TCPSocket 3310</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">TCPAddr 127.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">User _clamav</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DetectPUA yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertEncrypted yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertEncryptedArchive yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertEncryptedDoc yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertOLE2Macros yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertPhishingSSLMismatch yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">AlertPhishingCloak yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">MaxRecursion 12</span>
</span></span></code></pre></div><p>La dernière partie de configuration est à-propos de c-icap. Deux fichiers
de configurations ont besoin de modifications avant de permettre à c-icap
d&rsquo;utiliser ClamAV en tant que scanner de malware.</p>
<p>Le premier est <code>/etc/c-icap/c-icap.conf</code>. Ajoutez les lignes suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Include /etc/c-icap/clamd_mod.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Include /etc/c-icap/virus_scan.conf</span>
</span></span></code></pre></div><p>Vous devriez changer les valeurs suivantes dans ce fichier de manière
significative et différente :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">ServerAdmin admin@example.org</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ServerName scanner.example.org</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">TmpDir /tmp</span>
</span></span></code></pre></div><p>Il y a un défaut dans le fichier de configuration à-propos de la
journalisation. L&rsquo;option <code>Logger</code> est paramétrée vers <code>sys_logger</code>.
Mais le module <code>sys_logger</code> requis est chargé seulement plus tard dans
le fichier de configuration. Si vous voulez utiliser <code>sys_logger</code>, vous
devez charger le module avant de paramétrer l&rsquo;option <code>Logger</code>. Cela
empêchera c-icap de démarrer, bien que <a href="https://man.openbsd.org/rcctl" rel="external">rcctl(8)</a>
retournera ok. Soit vous changez l&rsquo;option <code>Logger</code> vers <code>file_logger</code>
soit vous déplacez les blocs dans le fichier de configuration pour
utiliser <code>sys_logger</code>.</p>
<p>Dans le fichier <code>/etc/c-icap/clamd_scan.conf</code>, faites les paramétrages
suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">clamd_mod.ClamdHost 127.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">clamd_mod.ClamdPort 3310</span>
</span></span></code></pre></div><h2 id="démarrer-les-services">Démarrer les services</h2>
<p>Puisque toute la configuration est faite, c&rsquo;est maintenant le moment
d&rsquo;activer et de démarrer les services :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ <span style="color:#815ba4">for</span> s in clamd c_icap ; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>&gt; rcctl enable <span style="color:#ef6155">$s</span>
</span></span><span style="display:flex;"><span>&gt; rcctl start <span style="color:#ef6155">$s</span>
</span></span><span style="display:flex;"><span>&gt; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><p>Soyez patient avec clamd. Il prend du temps à démarrer parce qu&rsquo;il
vérifie la base de données des signatures.</p>
<h2 id="tester-le-serveur-icap">Tester le serveur ICAP</h2>
<p>Tester votre démarrage est facile parce que c-icap est fourni avec un
client ICAP pour cette tâche : c-icap-client. Appellez-le sans arguments
effectuera un simple appel d&rsquo;OPTIONS pour vérifier si le server fonctionne :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ c-icap-client
</span></span><span style="display:flex;"><span>ICAP server:localhost, ip:127.0.0.1, port:1344
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OPTIONS:
</span></span><span style="display:flex;"><span>    Allow 204: Yes
</span></span><span style="display:flex;"><span>    Preview: <span style="color:#f99b15">1024</span>
</span></span><span style="display:flex;"><span>    Keep alive: Yes
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ICAP HEADERS:
</span></span><span style="display:flex;"><span>    ICAP/1.0 <span style="color:#f99b15">200</span> OK
</span></span><span style="display:flex;"><span>    Methods: RESPMOD, REQMOD
</span></span><span style="display:flex;"><span>    Service: C-ICAP/0.5.6 server - Echo demo service
</span></span><span style="display:flex;"><span>    ISTag: CI0001-XXXXXXXXX
</span></span><span style="display:flex;"><span>    Transfer-Preview: *
</span></span><span style="display:flex;"><span>    Options-TTL: <span style="color:#f99b15">3600</span>
</span></span><span style="display:flex;"><span>    Date: Sat, <span style="color:#f99b15">16</span> May <span style="color:#f99b15">2020</span> 10:02:03 GMT
</span></span><span style="display:flex;"><span>    Preview: <span style="color:#f99b15">1024</span>
</span></span><span style="display:flex;"><span>    Allow: <span style="color:#f99b15">204</span>
</span></span><span style="display:flex;"><span>    X-Include: X-Authenticated-User, X-Authenticated-Groups
</span></span><span style="display:flex;"><span>    Encapsulated: null-body<span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span></code></pre></div><hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Bruno Flückiger !</p>
<p><em>Cette page est la traduction de la page
<strong><a href="https://www.bsdhowto.ch/malware.html" rel="external">How to build a malware scan server</a></strong> du site <strong>BSDHowto.ch</strong>.</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;How to build a malware scan server&#39; de l&#39;auteur Bruno Flückiger.]]></summary>
        <published>2020-08-29T15:04:08+02:00</published>
        <updated>2023-05-03T06:30:55+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4520d57d-93dc-c690-c6b1-593d26f588fc</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/help/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: help : aide pour les nouveaux utilisateurs et administrateurs, sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="halp" scheme="http://doc.huc.fr.eu.org/fr/tags/halp/" />
        <content type="html"><![CDATA[<h2 id="utilisation">Utilisation</h2>
<p><code>help</code> en ligne de commande 8-)</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/help/#man-help">man help</a></li>
</ul>
<h3 id="man-help">man help</h3>
<h4 id="description">Description</h4>
<p>Ce document a pour but de familiariser les nouveaux utilisateurs et administrateurs
systèmes avec OpenBSD et, si nécessaire, avec UNIX en général.</p>
<p>En premier, une mine d&rsquo;informations est contenue dans les pages de manuel
système. Dans UNIX, la commande <a href="https://man.openbsd.org/man" rel="external">man(1)</a> est
utilisée pour les voir. Écrivez <strong>man man</strong> pour avoir les instructions
à-propos de comment l&rsquo;utiliser correctement. Prêtez une attention spéciale
à l&rsquo;option <strong>-k</strong>.</p>
<p>D&rsquo;autres références à OpenBSD incluent la FAQ (Foire aux Questions) localisée
à <strong><a href="https://www.openbsd.org/faq/" rel="external">https://www.openbsd.org/faq/</a></strong>, qui est plus à l&rsquo;attention des administrateurs
et qui présume que le lecteur possède une certaine connaissance d&rsquo;UNIX.
Il y a aussi des listes de diffusion en place où des questions sont posées
aux développeurs d&rsquo;OpenBSD et à d&rsquo;autres utilisateurs ;
voir <strong><a href="https://www.openbsd.org/mail.html" rel="external">https://www.openbsd.org/mail.html</a></strong>.</p>
<p>Les administrateurs systèmes devraient toujours lire la page de manuel
<a href="https://man.openbsd.org/afterboot.8" rel="external">afterboot(8)</a> qui explique une variété
de tâches qui sont typiquement assumées après le premier démarrage du système.
Durant la configuration du système, considérez en premier toutes implications
de sécurité possibles qui peuvent résulter de vos changements.</p>
<h5 id="le-shell-unix">Le shell Unix</h5>
<p>Après être connecté, certains messages systèmes sont typiquement affichés,
ensuite l&rsquo;utilisateur est capable d&rsquo;entrer des commandes à exécuter par
le programme shell. Le shell est un interpréteur en ligne de commande qui
lit les entrées utilisateur (normalement depuis un terminal) et exécute
des commandes. Différents shells sont disponibles ; OpenBSD est fourni avec
<a href="https://man.openbsd.org/csh" rel="external">csh(1)</a>, <a href="https://man.openbsd.org/ksh" rel="external">ksh(1)</a>,
et <a href="https://man.openbsd.org/sh" rel="external">sh(1)</a>. Chaque shell utilisateur est indiqué
dans le dernier champ correspondant à l&rsquo;entrée dans le fichier système
password (<strong>/etc/passwd</strong>).</p>
<h5 id="commandes-de-base-unix">Commandes de base Unix</h5>
<p><strong>man</strong> interface aux pages de manuel système. Concernant toutes les commandes
listées ci-dessous, écrivez <strong>man</strong> <strong>command</strong> pour obtenir l&rsquo;information
détaillée sur ce qu&rsquo;elle fait et comment l&rsquo;utiliser.</p>
<p><strong>pwd</strong> imprime le chemin en cours. Les fichiers sont organisés en hiérarchie
(voir <a href="https://man.openbsd.org/hier.7" rel="external">hier(7)</a> appelée arborescence.
Cette commande indiquera dans quel répertoire vous êtes actuellement localisé.</p>
<p><strong>cd</strong> change le chemin de travail. Utilisez cette commande pour naviguer
au-travers de la hiérarchie fichier. Par exemple, écrivez <strong>cd /</strong> pour
changer de répertoire de travail vers root.</p>
<p><strong>ls</strong> liste le contenu du répertoire. Écrivez <strong>ls -l</strong> pour une liste
détaillée.</p>
<p><strong>cat</strong> bien qu&rsquo;il est plusieurs utilisations possibles,
<strong>cat</strong> <strong>filename</strong> affichera le contenu d&rsquo;un fichier texte à l&rsquo;écran.</p>
<p><strong>vi</strong> édite les fichiers textes. Par exemple, <strong>vi</strong> <strong>filename</strong>.
Voir aussi <a href="https://man.openbsd.org/mg" rel="external">mg(1)</a>.</p>
<p><strong>mkdir</strong> crée un répertoire. Par exemple, <strong>mkdir</strong> <strong>dirname</strong>.</p>
<p><strong>rmdir</strong> supprime un répertoire.</p>
<p><strong>rm</strong> supprime des fichiers. Les fichiers sont généralement supprimés
par leurs propriétaires. Voir la commande <a href="https://man.openbsd.org/chmod" rel="external">chmod(1)</a>
pour avoir les informations sur les permissions de fichier.</p>
<p><strong>chmod</strong> change les modes de fichier, incluant les permissions.
L&rsquo;utilisation n&rsquo;est pas immédiatement évidente ; veuillez lire sa page
de manuel avec attention, à-propos des permissions de fichiers, spécifiquement
sur les fichiers systèmes, qui sont vitaux pour maintenir la sécurité et
l&rsquo;intégrité.</p>
<p><strong>cp</strong> copie des fichiers.</p>
<p><strong>mv</strong> déplace et renomme des fichiers.</p>
<p><strong>ps</strong> liste les processus actifs. La plupart des systèmes basés sur UNIX,
incluant OpenBSD, sont multi-tâches, ce qui signifie que beaucoup de programment
partagent les ressources systèmes en même temps. Un usage commun est <strong>ps -auxw</strong>,
qui affichera les informations à-propos de tous les processus actifs.</p>
<p><strong>kill</strong> tue les processus. Utilisé la plupart du temps pour arrêter des
programmes ne s&rsquo;exécutant pas normalement, mais aussi pour signaler des
programmes demandant certaines opérations (e.g., relire leur configuration).</p>
<p><strong>date</strong> affiche la date et l&rsquo;heure système actuelle.</p>
<p><strong>mail</strong> accède à la boite mail.</p>
<p><strong>exit</strong> se déconnecte du système.</p>
<p>Quand une commande est entrée, il est vérifié en premier si elle est interne
au shell. Si ce n&rsquo;est pas le cas, le shell parcours tout répertoire contenu
dans la variable d&rsquo;environnement PATH (voir <a href="https://man.openbsd.org/environ.7" rel="external">environ(7)</a>).
Si la commande n&rsquo;est pas trouvée, un message d&rsquo;erreur est affiché.
Autrement, le shell exécute la commande, passant les arguments spécifiés
dans la ligne de commande.</p>
<p>Les commandes internes au shell n&rsquo;ont pas leur propre page de manuel, il
est ainsi nécessaire de lire la page de manuel du shell utilisateur.
Des outils tels que <a href="https://man.openbsd.org/which" rel="external">which(1)</a> et &ldquo;whence&rdquo;,
une commande interne à <a href="https://man.openbsd.org/ksh" rel="external">ksh(1)</a>, peuvent être
utilisés pour voir les commandes en cours d&rsquo;exécution.</p>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="https://man.openbsd.org/csh" rel="external">csh(1)</a>, <a href="https://man.openbsd.org/ksh" rel="external">ksh(1)</a>, <a href="https://man.openbsd.org/man" rel="external">man(1)</a>, <a href="https://man.openbsd.org/whatis" rel="external">whatis(1)</a>, <a href="https://man.openbsd.org/whereis" rel="external">whereis(1)</a>, <a href="https://man.openbsd.org/which" rel="external">which(1)</a>, <a href="https://man.openbsd.org/afterboot.8" rel="external">afterboot(8)</a></li>
</ul>
<h4 id="histoire">Histoire</h4>
<p>Cette page de manuel a été écrite par Aaron Campbell <a href="mailto:aaron@openbsd.org" rel="external">aaron@openbsd.org</a> et est apparue la première fois dans OpenBSD 2.6.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment aider les administrateurs systèmes, grâce à la commande &#39;help&#39;, sous OpenBSD]]></summary>
        <published>2020-08-27T05:05:36+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9b59b1b1-13c7-e16e-15e7-43fe9cc460da</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sshguard/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSHGuard : se protéger des attaques par force brute sur sshd et autres (services) / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="SSHGuard" scheme="http://doc.huc.fr.eu.org/fr/tags/sshguard/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>SSHGuard</strong> protège les hôtes des attaques par force brute. Il supporte
IPv6, gère des listes blanches et journalise l&rsquo;authentification ; il
s&rsquo;interface avec les plus grands systèmes pare-feu, a un analyseur de
journaux remarquablement intelligent, et est indépendant, rapide et
léger puisqu&rsquo;écrit en C.</p>
<p>www : <a href="http://www.sshguard.net" rel="external">http://www.sshguard.net</a></p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>sshguard</code></strong>.</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/sshguard/#man-8-sshguard">man 8 sshguard</a></li>
<li><code>man 7 sshguard-setup</code></li>
<li><code>less /usr/local/share/doc/[[#pkg-readme|pkg-readmes]]/sshguard</code></li>
<li><code>less /usr/local/share/examples/sshguard/sshguard.conf.sample</code></li>
<li><a href="/fr/sys/openbsd/sshguard/#pkg-readme">pkg-readme</a></li>
</ul>
<h3 id="man-8-sshguard">man 8 sshguard</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>sshguard</strong> [<strong>-hv</strong>] [<strong>-a</strong> threshold] [<strong>-b</strong> threshold:blacklist_file] [<strong>-i</strong> pidfile] [<strong>-p</strong> blocktime] [<strong>-s</strong> detection_time] [<strong>-w</strong> address | whitelist_file] [file &hellip;]</p>
<h4 id="description-1">Description</h4>
<p><strong>sshguard</strong> protège les hôtes des attaques par force brute contre SSH
et d&rsquo;autres services. Il aggrége les journaux systèmes et bloque les
récidives en utilisant un des nombreux backend pare-feu.</p>
<p><strong>sshguard</strong> peut surveiller les fichiers des journaux ou lire les
messages depuis l&rsquo;entrée standard. Les messages sont analysés ligne par
ligne selon des patterns reconnus. Une attaque est détectée lorsque
plusieurs patterns correspondent dans une intervalle de temps définie.
Les attaquants sont bloqués temporairement mais peuvent aussi être bannis
de manière semi-permanente en utilisant l&rsquo;option blacklist.</p>
<h4 id="options">Options</h4>
<ul>
<li>
<p><strong>-a</strong> <strong>threshold</strong> (<strong>default 30</strong>) <br>
Bloque les attaquants lorsque leur score d&rsquo;attaque cumulée excède un
<strong>seuil</strong>. La plupart des attaques ont un score de 10.</p>
</li>
<li>
<p><strong>-b</strong> <strong>threshold:blacklist_file</strong> <br>
Blackliste un attaquant lorsque son score excède le <strong>seuil</strong>. Les
adresses blacklistées sont chargées et ajoutées dans un
<strong>fichier de blackliste</strong>.</p>
</li>
<li>
<p><strong>-i</strong> <strong>pidfile</strong> <br>
Écrit le PID de <strong>sshguard</strong> vers le fichier <strong>pidfile</strong>.</p>
</li>
<li>
<p><strong>-p</strong> <strong>blocktime</strong> (<strong>default 120</strong>) <br>
Bloque les attaquants selon un <strong>temps de blocage</strong> en seconde après
avoir atteint le <strong>seuil</strong>. Les blocages suivants sont incrémentés
d&rsquo;un facteur de 1.5. <br>
<strong>sshguard</strong> débloque les attaques à intervalles aléatoires, ainsi
les temps de blocages actuels seront plus longs.</p>
</li>
<li>
<p><strong>-s</strong> <strong>detection_time</strong> (<strong>default 1800</strong>) <br>
Se souvenir de potentiels attaquants durant un <strong>temp de détection</strong>
en secondes avant de réinitialiser leur score.</p>
</li>
<li>
<p>[<strong>-w</strong> <strong>address</strong> | <strong>whitelist_file</strong>] <br>
Une liste blanche est une simple adresse, ou un bloc d&rsquo;adresse.
Cette option peut être utilisée plusieurs fois. Alternativement, il
est possible de fournir un chemin absolu vers une fichier de liste
blanche contenant des adresses. Voir la section <a href="/fr/sys/openbsd/sshguard/#liste-blanche">Liste Blanche</a></p>
</li>
<li>
<p><strong>-h</strong> affiche l&rsquo;information d&rsquo;utilisation puis sort.</p>
</li>
<li>
<p><strong>-v</strong> affiche l&rsquo;information de version puis sort.</p>
</li>
</ul>
<h4 id="environnement">Environnement</h4>
<ul>
<li><strong>SSHGUARD_DEBUG</strong> <br>
Permet d&rsquo;activer la sortie verbeuse depuis sshg-blocker.</li>
</ul>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><strong>/etc/sshguard.conf</strong> <br>
Lire le fichier d&rsquo;exemple de configuration dans
<code>/usr/local/share/examples/sshguard/sshguard.conf.sample</code>.</li>
</ul>
<h4 id="liste-blanche">Liste Blanche</h4>
<p>Les adresses en liste blanche ne sont jamais bloquées. Les adresses
peuvent être spécifiées depuis la ligne de commande ou être enregistrées
dans un fichier.</p>
<p>En ligne de commande, écrivez l&rsquo;option <strong>-w</strong> une ou plusieurs fois avec
une adresse IP, un bloc d&rsquo;adresses CIDR, ou un nom d&rsquo;hôte en argument.
Les noms d&rsquo;hôtes sont résolus une fois lors du démarrage. Si un nom
d&rsquo;hôte résoud de multiples adresses, elles sont toutes mises en liste
blanches.</p>
<p>Par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sshguard -w 192.168.1.10 -w 192.168.0.0/24 -w friend.example.com
</span></span><span style="display:flex;"><span>              -w 2001:0db8:85a3:0000:0000:8a2e:0370:7334
</span></span><span style="display:flex;"><span>              -w 2002:836b:4179::836b:0000/126
</span></span></code></pre></div><p>Si l&rsquo;argument donné à <strong>-w</strong> commence avec un &lsquo;/&rsquo; ou un &lsquo;.&rsquo;, l&rsquo;argument
est traité en tant que chemin vers une fichier de liste blanche.</p>
<p>Le fichier de liste blanche contient des commentaires <em>(des lignes
commençant avec &lsquo;#&rsquo;)</em>, des adresses, des blocs d&rsquo;adresses, ou des noms
d&rsquo;hôtes, un par ligne.</p>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li>sshguard-setup(7)</li>
</ul>
<hr>
<p>2.3,                             9 Janvier 2017,                    SSHGUARD(8)</p>
<hr>
<h3 id="pkg-readme">pkg-readme</h3>
<p>Pour utiliser sshguard avec pf(4), ajouter quelque chose de similaire à
ce qui suit dans votre fichier <code>/etc/pf.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;sshguard&gt; persist</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in quick on egress proto tcp from &lt;sshguard&gt; \</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">to any port ssh label &#34;ssh bruteforce&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Se protéger des attaques par force brute sur le serveur SSH sous OpenBSD.]]></summary>
        <published>2020-08-27T03:04:57+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5e924de6-4a8c-2b24-793c-952228e78b9d</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-search-jqueryui-autocomplete-json/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo Search : un moteur de recherche interne (JQueryUI: Autocomplete &#43; JSON)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="search" scheme="http://doc.huc.fr.eu.org/fr/tags/search/" />
        <category term="JQuery" scheme="http://doc.huc.fr.eu.org/fr/tags/jquery/" />
        <category term="JSON" scheme="http://doc.huc.fr.eu.org/fr/tags/json/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il y a quelques mois, j&rsquo;ai écrit ce premier article pour obtenir un
moteur de recherche basique en s&rsquo;aidant de la méthode <code>autocomplete()</code> de
JQueryUI : 
<a class="inside" href="/fr/web/hugo/hugo-search-jqueryui-autocomplete/" title="Lien interne vers l&#39;article : 'Hugo Search : un moteur de recherche interne (JQueryUI Autocomplete)'">Hugo Search : un moteur de recherche interne (JQueryUI Autocomplete)</a>

</p>
<p>Et, puis je me suis rappelé que, parmi les flux de syndication, j&rsquo;en génère
un au format JSON, le bien nommé <strong>feed.json</strong>, <em>disponible à partir
de la page d&rsquo;accueil</em>. Je me suis demandé si je pouvais réutiliser mon
code, et je découvre que notre fameux <abbr title="Static Site Generator">SSG</abbr>

Hugo a une fonction native <code>getJSON</code>.</p>
<p>Reprenons le code…</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne fonctionne pas en environnement de développement !</div>

<h2 id="code">Code</h2>
<h3 id="hugo">Hugo</h3>
<p>Je construis une variable <code>$feed</code> qui injectera la valeur du chemin absolu
de mon fichier <strong>feed.json</strong>.</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{- $baseURL := site.BaseURL | absLangURL -}}
{{- $feed :=  urls.JoinPath $baseURL &#34;/feed.json&#34; | absLangURL -}}
</code></pre><h3 id="jquery">JQuery</h3>
<p>La partie du code JQuery est sensiblement la même, à la différence près
est que la fonction <code>range</code> d&rsquo;Hugo va directement appeler le contenu retourné
par la fonction <code>getJSON</code>. La suite du traitement est faite par la méthode
<code>autocomplete()</code> de JQuery, ni plus ni moins.</p>
<p>Voici le code :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span>{{<span style="color:#5bc4bf">-</span> <span style="color:#815ba4">with</span> <span style="color:#06b6ef">resources</span>.<span style="color:#06b6ef">Get</span> <span style="color:#06b6ef">$feed</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span><span style="color:#776e71">&lt;!--</span> <span style="color:#06b6ef">Javascript</span> <span style="color:#5bc4bf">--&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span><span style="color:#06b6ef">script</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$</span>(<span style="color:#815ba4">function</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">var</span> <span style="color:#06b6ef">projects</span> <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">range</span> .<span style="color:#06b6ef">items</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">value</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ safeHTML .title }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">label</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ safeHTML .summary }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">url</span><span style="color:#5bc4bf">:</span><span style="color:#48b685">&#34;{{ safeURL .url }}&#34;</span>
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">end</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        ];
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">autocomplete</span>({
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">minLength</span><span style="color:#5bc4bf">:</span> <span style="color:#f99b15">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">source</span><span style="color:#5bc4bf">:</span> <span style="color:#06b6ef">projects</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">focus</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">select</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#replyer&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#06b6ef">data</span>(<span style="color:#48b685">&#39;ui-autocomplete&#39;</span>).<span style="color:#06b6ef">_renderItem</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">function</span>(<span style="color:#06b6ef">ul</span>, <span style="color:#06b6ef">item</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#39;&lt;li&gt;&#39;</span>)
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">append</span>(<span style="color:#48b685">&#39;&lt;a href=&#34;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">url</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34; alt=&#34;&#39;</span><span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34;&gt;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&lt;/a&gt;&#39;</span> )
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">appendTo</span>(<span style="color:#06b6ef">ul</span>);
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span><span style="color:#ef6155">/script&gt;</span>
</span></span><span style="display:flex;"><span>{{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">end</span> <span style="color:#5bc4bf">-</span>}}
</span></span></code></pre></div><h3 id="html">HTML</h3>
<p>La partie de code HTML est toujours aussi simple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;form-control&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">placeholder</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ T &#34;</span><span style="color:#06b6ef">searchHolderTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">aria-hidden</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;true&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;replyer&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;hidden&#34;</span>&gt;
</span></span></code></pre></div><h3 id="tldr">TL;DR</h3>
<p>L&rsquo;ensemble du code :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;form-control&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">placeholder</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ T &#34;</span><span style="color:#06b6ef">searchHolderTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">aria-hidden</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;true&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;replyer&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;hidden&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    {{- $baseURL := site.BaseURL | absLangURL -}}
</span></span><span style="display:flex;"><span>    {{- $feed :=  urls.JoinPath $baseURL &#34;/feed.json&#34; | absLangURL -}}
</span></span><span style="display:flex;"><span>    {{- with resources.Get $feed -}}
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">&lt;!-- Javascript --&gt;</span>
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">script</span>&gt;
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$</span>(<span style="color:#815ba4">function</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">var</span> <span style="color:#06b6ef">projects</span> <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">range</span> .<span style="color:#06b6ef">items</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">value</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ safeHTML .title }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">label</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ safeHTML .summary }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">url</span><span style="color:#5bc4bf">:</span><span style="color:#48b685">&#34;{{ safeURL .url }}&#34;</span>
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">end</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        ];
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">autocomplete</span>({
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">minLength</span><span style="color:#5bc4bf">:</span> <span style="color:#f99b15">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">source</span><span style="color:#5bc4bf">:</span> <span style="color:#06b6ef">projects</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">focus</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">select</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#replyer&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#06b6ef">data</span>(<span style="color:#48b685">&#39;ui-autocomplete&#39;</span>).<span style="color:#06b6ef">_renderItem</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">function</span>(<span style="color:#06b6ef">ul</span>, <span style="color:#06b6ef">item</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#39;&lt;li&gt;&#39;</span>)
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">append</span>(<span style="color:#48b685">&#39;&lt;a href=&#34;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">url</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34; alt=&#34;&#39;</span><span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34;&gt;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&lt;/a&gt;&#39;</span> )
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">appendTo</span>(<span style="color:#06b6ef">ul</span>);
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#5bc4bf">script</span>&gt;
</span></span><span style="display:flex;"><span>    {{- end -}}
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><hr>
<p>Voilà !</p>
<hr>
<h3 id="erreur">Erreur</h3>
<p><abbr title="Question">Q</abbr>
 : Lors de la génération en local, vous avez une
multitude d&rsquo;erreur, telle que la suivante et le serveur s&rsquo;arrête
tout seul : <br>
<code>ERROR 2020/08/27 08:16:41 Failed to get JSON resource “http://localhost:1313/fr/feed.json”: Get “http://localhost:1313/fr/feed.json”: dial tcp [::1]:1313: connect: connection refused</code></p>
<p><abbr title="Réponse">R</abbr>
 : En environnement local, le serveur n&rsquo;est pas
capable d&rsquo;appeler une donnée qui n&rsquo;est pas encore générée.</p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li>La documentation officielle : <a href="https://gohugo.io/tools/search/" title="Lien vers la page du site officiel Hugo : Tools &gt; Search">Hugo Documentation : Tools &gt; Search</a>
 - <em>lien en anglais</em></li>
<li>La fonction Hugo <code>getJSON</code> : <a href="https://gohugo.io/templates/data-templates/#load-local-files" title="Lien vers la page du site officiel Hugo : Templates &gt; Data templates">Hugo Documentation : Templates &gt; Data templates</a>
 - <em>lien en anglais</em></li>
<li>La méthode JQuery UI <code>autocomplete()</code> : <a href="https://jqueryui.com/autocomplete" rel="external">https://jqueryui.com/autocomplete</a> - <em>lien en anglais</em></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le flux JSON pour intégrer un &#39;moteur de recherche&#39; dans Hugo, avec JQuery UI autocomplete()]]></summary>
        <published>2020-08-25T23:32:48+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:bbc478db-7901-e555-d1e1-ced4f8accae9</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/bsdhowto.ch/externaldns/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Comment créer un serveur de noms avec DNS-over-TLS (DoT)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DoT" scheme="http://doc.huc.fr.eu.org/fr/tags/dot/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://www.bsdhowto.ch/externaldns.html" rel="external">How to build a name server with DNS over TLS (DoT)</a></strong>&rdquo;,
écrit par Bruno Flückiger.</p>
<hr>
<p>Date : 2020-08-25</p>
<h2 id="introduction">Introduction</h2>
<p>Cet article est en rapport avec la configuration de <a href="https://man.openbsd.org/nsd" rel="external">nsd(8)</a>
en tant que serveur de noms public pour votre propre domaine, fournissant
DNS-over-TLS (DOT). Tout ce qui faut pour cette tâche est inclus dans
l&rsquo;installation de base d&rsquo;OpenBSD. Vous n&rsquo;avez besoin d&rsquo;installer aucun
paquet additionnel pour cela.</p>
<h2 id="certificats">Certificats</h2>
<p>Tout fournisseur de certificats qui supporte le protocole <a href="https://tools.ietf.org/html/rfc8555" rel="external">ACME</a>
peut être utilisé. Personnellement, j&rsquo;utilise le plus populaire
actuellement : <a href="https://letsencrypt.org/" rel="external">Let&rsquo;s Encrypt</a>.</p>
<p>Les challenges reçus du fournisseur de certificats seront utilisés par
<a href="https://man.openbsd.org/httpd" rel="external">httpd(8)</a> en configurant <code>/etc/httpd.conf</code>,
similaire à ceci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server &#34;ns1.example.net&#34; {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on egress port http</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">root &#34;/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/.well-known/acme-challenge/*&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">request strip 2</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/acme&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">types {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">include &#34;/usr/share/misc/mime.types&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Testez votre configuration, puis activez et démarrez httpd(8) :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas httpd -n
</span></span><span style="display:flex;"><span>$ doas rcctl enable httpd
</span></span><span style="display:flex;"><span>$ doas rcctl start httpd
</span></span></code></pre></div><p>L&rsquo;étape suivante est de configurer acme-client(1). Je vous suggère
d&rsquo;utiliser <code>/etc/examples/acme-client.conf</code> en tant que source à
sauvegarder puis à modifier conséquemment. Le fichier <code>acme-client.conf</code>
résultant devrait être sauvegardé dans <code>/etc</code> et ressemblait à :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">authority letsencrypt {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">api url &#34;https://acme-v02.api.letsencrypt.org/directory&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">account key &#34;/etc/acme/letsencrypt-privkey.pem&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">authority letsencrypt-staging {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">api url &#34;https://acme-staging.api.letsencrypt.org/directory&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">account key &#34;/etc/acme/letsencrypt-staging-privkey.pem&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">domain ns1.bsdhowto.ch {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">domain key &#34;/etc/ssl/acme/private/ns1.bsdhowto.ch.key&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">domain certificate &#34;/etc/ssl/acme/ns1.bsdhowto.ch.crt&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">domain full chain certificate &#34;/etc/ssl/acme/ns1.bsdhowto.ch.fullchain.pem&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">sign with letsencrypt</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Avant d&rsquo;avoir votre certificat, vous devriez vous assurer que
<a href="https://man.openbsd.org/pf" rel="external">pf(4)</a> laisse passer les requêtes vers
<a href="https://man.openbsd.org/pf.conf" rel="external">httpd(8)</a>. Ajoutez une règle similaire
à la suivante dans votre fichier pf.conf(5) :</p>
<p><code>pass in on egress proto tcp from any to egress port http</code></p>
<p>Vérifiez la configuration dans <code>/etc/pf.conf</code> puis chargez-la dans pf(4)
en utilisant les commandes suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas pfctl -nf /etc/pf.conf
</span></span><span style="display:flex;"><span>$ doas pfctl -f /etc/pf.conf
</span></span></code></pre></div><p>Maintenant vous êtes prêt à récupérer le certificat pour nsd(8).
N&rsquo;oubliez pas de créer le fichier OCSP aussi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ <span style="color:#ef6155">dest</span><span style="color:#5bc4bf">=</span>/etc/ssl/ns1.example.net
</span></span><span style="display:flex;"><span>$ doas acme-client ns1.example.net
</span></span><span style="display:flex;"><span>$ doas ocspcheck -No <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.ocsp <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.fullchain.pem
</span></span></code></pre></div><p>Vous devez vous assurer que le certificat soit valide, de même pour la
réponse OCSP, et qu&rsquo;ils soient renouvelés avant leurs expirations. Je
vous suggère d&rsquo;ajouter quelque chose comme ceci dans <code>/etc/daily.local</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dest</span><span style="color:#5bc4bf">=</span>/etc/ssl/ns1.example.net
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>acme-client ns1.example.net
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$?</span> -eq <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span> ; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    ocspcheck -No <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.ocsp <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.fullchain.pem
</span></span><span style="display:flex;"><span>    rcctl restart nsd
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>oscpcheck -i <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.ocsp <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.fullchain.pem
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$?</span> -eq <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">]</span> ; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    ocspcheck -No <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.ocsp <span style="color:#f99b15">${</span><span style="color:#ef6155">dest</span><span style="color:#f99b15">}</span>.fullchain.pem
</span></span><span style="display:flex;"><span>    rcctl restart nsd
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><p>Le script vérifie en premier le certificat. S&rsquo;il a été renouvelé , il
récupère la réponse OCSP pour le nouveau certificat et redémarre nsd(8)
afin de charger les nouveaux fichiers. À la seconde étape, le script
vérifie si la réponse OCSP a expirée. Si c&rsquo;est le cas, il récupère une
nouvelle réponse OCSP et redémarre nsd(8) afin de charger la nouvelle
réponse OCSP.</p>
<h2 id="configuration-de-nsd8">Configuration de nsd(8)</h2>
<p>La configuration correcte de nsd(8) dépend du rôle de votre serveur :
primaire ou secondaire. La plupart des fournisseurs de domaines
requièrent que vous exécutiez au moins deux serveurs de noms, de
préférence dans deux différents sous-réseaux. Je vous montre la
configuration des deux.</p>
<p>Voici la première pour le primaire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-identity: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-version: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 192.0.2.11</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 192.0.2.11@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 2001:db8:1::c000:020b</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 2001:db8:1::c000:020b@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">server-count: 1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">statistics: 86400</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-key: &#34;/etc/ssl/ns1.example.net.key&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-pem: &#34;/etc/ssl/ns1.example.net.fullchain.pem&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-ocsp: &#34;/etc/ssl/ns1.example.net.ocsp&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">remote-control:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-enable: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">key:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">algorithm: sha256</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">secret: &#34;IAmASecretKeyForDomainTransfers&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">zone:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: &#34;example.net&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">zonefile: &#34;/var/nsd/zones/master/%s.dns&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">notify: 198.51.100.12 nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">notify: 2001:db8:2::c633:640c nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">provide-xfr: 198.51.100.12 nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">provide-xfr: 2001:db8:2::c633:640c nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">outgoing-interface: 192.0.2.11</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">outgoing-interface: 2001:db8:1::c000:020b</span>
</span></span></code></pre></div><p>Assurez vous que le serveur primaire et le secondaire utilise la même
clé secrète pour le transfert de domaines, autrement cela ne fonctionnera
pas. Vous pouvez générer le secret pour la clé de transfert de domaine
en utilisant la commande suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ <span style="color:#815ba4">for</span> i in <span style="color:#815ba4">$(</span>jot -r -s <span style="color:#48b685">&#34; &#34;</span> <span style="color:#f99b15">32</span> <span style="color:#f99b15">0</span> 255<span style="color:#815ba4">)</span> ; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>&gt; echo <span style="color:#f99b15">${</span><span style="color:#ef6155">i</span><span style="color:#f99b15">}</span> | awk <span style="color:#48b685">&#39;{ printf &#34;%c&#34;, $1 }&#39;</span>
</span></span><span style="display:flex;"><span>&gt; <span style="color:#815ba4">done</span> | sha256 -b
</span></span></code></pre></div><p>La prochaine étape est de s&rsquo;assurer que le fichier de votre zone contient
certaines données valides. Soit vous avez déjà un fichier de zone valide,
soit vous pouvez utiliser celui qui suit en tant que point de départ :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">$ORIGIN .</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$TTL 3600   ; 1 hour</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">example.net IN  SOA ns1.example.net. hostmaster.example.net. (</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">1   ; serial</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">10800   ; refresh (3 hours)</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">600 ; retry (10 minutes)</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">241900  ; expire (4 weeks)</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">3600    ; minimum (1 hour)</span>
</span></span><span style="display:flex;"><span>                <span style="color:#06b6ef">)</span>
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">NS  ns1.example.net.</span>
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">NS  ns2.example.net.</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$ORIGIN example.net.</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ns1         A   192.0.2.11</span>
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">AAAA    2001:db8:1::c000:020b</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ns2         A   198.51.100.12</span>
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">AAAA    2001:db8:2::c633:640c</span>
</span></span></code></pre></div><p>La configuration du second serveur a besoin d&rsquo;autres options légèrement
différentes pour en faire un serveur secondaire, mais elle ressemble à
celle du serveur primaire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-identity: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">hide-version: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 198.51.100.12</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 198.51.100.12@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 2001:db8:2::c633:640c</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ip-address: 2001:db8:2::c633:640c@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">server-count: 1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">statistics: 86400</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-key: &#34;/etc/ssl/ns2.example.net.key&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-pem: &#34;/etc/ssl/ns2.example.net.fullchain.pem&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tls-service-ocsp: &#34;/etc/ssl/ns2.example.net.ocsp&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">remote-control:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">control-enable: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">key:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">algorithm: sha256</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">secret: &#34;IAmASecretKeyForDomainTransfers&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">zone:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: &#34;example.net&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">zonefile: &#34;/var/nsd/zones/slave/%s.dns&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">allow-notify: 192.0.2.11 nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">allow-notify: 2001:db8:1::c000:020b nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">request-xfr: 192.0.2.11 nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">request-xfr: 2001:db8:1::c000:020b nskey.example.net</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">outgoing-interface: 198.51.100.12</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">outgoing-interface: 2001:db8:2::c633:640c</span>
</span></span></code></pre></div><p>Sur les deux serveurs, vous devez exécuter la commande suivant pour
prendre le contrôle à distance pour que l&rsquo;utilisation de nsd-control(8)
fonctionne :
<code>$ doas nsd-control-setup</code></p>
<p>Maintenant, il faut vérifier votre configuration. Exécutez la commande
suivante sur chacun des serveurs afin de trouver des erreurs de
typographie :
<code>$ doas nsd-checkconf /var/nsd/etc/nsd.conf</code></p>
<p>Si tout semble bon, vous êtes prêt pour activer et démarrer nsd(8) sur
les deux serveurs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas rcctl enable nsd
</span></span><span style="display:flex;"><span>$ doas rcctl start nsd
</span></span></code></pre></div><p>La dernière pièce du puzzle sont les règles pour pf(4) afin d&rsquo;autoriser
l&rsquo;accès externe à nsd(8). Ajoutez ces deux lignes à <code>/etc/pf.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto { tcp udp } from any to egress port domain</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto { tcp udp } from any to egress port domain-s</span>
</span></span></code></pre></div><p>Vérifiez puis chargez la configuration changée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas pfctl -nf /etc/pf.conf
</span></span><span style="display:flex;"><span>$ doas pfctl -f /etc/pf.conf
</span></span></code></pre></div><hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Bruno Flückiger !</p>
<p><em>Cette page est la traduction de la page <strong><a href="https://www.bsdhowto.ch/externaldns.html" rel="external">How to build a name server with DNS over TLS (DoT)</a></strong> du site <strong>BSDHowto.ch</strong>.</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;How to build a name server with DNS over TLS (DoT)&#39; de l&#39;auteur Bruno Flückiger.]]></summary>
        <published>2020-08-25T13:40:59+02:00</published>
        <updated>2023-05-03T06:30:55+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:834b0c6c-d9ea-69a2-e902-e4e6a08404e2</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-error-504-gateway-timeout/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Erreur 504 Gateway Timeout</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="504" scheme="http://doc.huc.fr.eu.org/fr/tags/504/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le serveur web nginx affiche une &ldquo;belle page blanche&rdquo; avec la mention
<strong>Error 504: Gateway timeout</strong> !</p>
<p>Cette erreur indique que le serveur web nginx agit comme une passerelle et
ne peut délivrer le contenu. Le serveur ne peut traiter dans un temps
imparti la requête demandée, la connexion est alors fermée.</p>
<p>Il peut y avoir plusieurs raisons, un élément réseau défectueux, mais aussi
un des paramètres suivants mal configurés :</p>
<p>Si vous utilisez PHP-FPM, vérifiez les écritures des directives :</p>
<ul>
<li><code>fastcgi_*_timeout</code></li>
<li><code>proxy_*_timeout</code></li>
<li><code>send_timeout</code></li>
</ul>
<p>Par défaut, toutes ces directives sont de 60 secondes. <br>
Des valeurs, en temps de secondes, trop basses impactent le serveur nginx
et lui empêchent de délivrer la requête…</p>
<p>Exemple, augmentez dans votre contexte <code>http</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">proxy_connect_timeout</span>  <span style="color:#f99b15">600</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">proxy_read_timeout</span>    <span style="color:#f99b15">600</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">proxy_send_timeout</span>    <span style="color:#f99b15">600</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">send_timeout</span>      <span style="color:#f99b15">600</span>;
</span></span></code></pre></div><p>Et, concernant le contexte <code>location</code> lié à PHP, ajoutez, par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">fastcgi_connect_timeout</span> <span style="color:#f99b15">330</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fastcgi_read_timeout</span> <span style="color:#f99b15">330</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fastcgi_send_timeout</span> <span style="color:#f99b15">330</span>;
</span></span></code></pre></div><p>Ceci étant fait, redémarrez le serveur !</p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_connect_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_connect_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_send_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_send_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout</a></li>
<li><a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout" rel="external">https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre cette erreur - Error 504: Gateway Timeout - de passerelle/proxy (PHP, FastCGI) sous nginx]]></summary>
        <published>2020-08-22T17:18:25+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:17493ed1-6ae5-205c-69db-9f8d3ed9b4a1</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-error-403-forbidden/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Erreur 403  Forbidden</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="403" scheme="http://doc.huc.fr.eu.org/fr/tags/403/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il peut y avoir plusieurs raisons pour laquelle nginx affiche une erreur 403.
Le serveur comprend la requête mais refuse de répondre au client web.</p>
<p>Les raisons :</p>
<ol>
<li>
<p>Une mauvaise configuration du chemin vers le fichier de configuration
du contexte server.</p>
</li>
<li>
<p>Un problème de droits sur le système de fichiers de la racine web, généralement
<code>/var/www/</code>.</p>
</li>
</ol>
<p>Par exemple, quelques lignes de log d&rsquo;erreur :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">2020/08/22 10:50:18 [error] 77863#0: *2 directory index of &#34;/htdocs/&#34; is forbidden, (…)
2020/08/22 10:52:21 [error] 890#0: *1 open() &#34;/htdocs/robots.txt&#34; failed (2: No such file or directory), (…)
</code></pre><p><strong>Vérifiez :</strong></p>
<ol>
<li>
<p>Les écritures des chemins web. Exemple dans le fichier de configuration
principal de nginx, les <code>include</code> vers <code>sites-enabled</code> sont ils corrects ?<br>
Il suffit d&rsquo;une erreur de typographie…</p>
</li>
<li>
<p>La racine web doit avoir, normalement pour droits utilisateurs, les noms
utilisateur et groupe web… <code>www-data:www-data</code>, ou <code>www:www</code><br>
<em>sauf cas particulier, tel sous OpenBSD <code>root:daemon</code></em>\</p>
</li>
<li>
<p>Les droits systèmes devraient être de type <code>0755</code>.</p>
</li>
</ol>
<p>Une fois la situation rétablie, redémarrer/recharger nginx.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;erreur 403 - Error 403: Forbidden - pour nginx]]></summary>
        <published>2020-08-22T16:45:32+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8827e769-4ed4-4e14-750c-70cad3179c85</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-brotli-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx &#43; Brotli / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="brotli" scheme="http://doc.huc.fr.eu.org/fr/tags/brotli/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Sous OpenBSD, il n&rsquo;y a pas encore de port du module <a href="https://github.com/google/ngx_brotli" rel="external">nginx-brotli</a>, donc la
gestion de la compression au format Brotli semble compromise.<br>
Et, bien :  non !</p>
<p>Version :</p>
<ul>
<li>OpenBSD : 6.7, 6.8</li>
<li>nginx : 1.16.1, 1.18.0</li>
<li>brotli : 1.0.7</li>
</ul>
<p><strong>nginx</strong> et <strong>brotli</strong> ne sont pas dans le système de base, mais dans les
ports. À installer avec la commande <code>pkg_add</code>…</p>
<hr>
<p>Étant donné qu&rsquo;il n&rsquo;est pas recommandé d&rsquo;activer la compression à la volée -
<em>sauf au doux sacrifice d&rsquo;usage de techniques <a class="tag" href="/fr/tags/csp">CSP</a>
 et de contrôle
absolu sur l&rsquo;émetteur du contenu compressé à la volée</em> -, dans ce mémo,
nous nous concentrerons sur la délivrance de contenu compressé de fichiers statiques.</p>
<p>Il y a une manière assez simple de mettre en place :</p>
<ol>
<li>Compresser les fichiers statiques au format brotli avant l&rsquo;envoi sur
l&rsquo;espace web</li>
<li>Au sein de nginx :
<ul>
<li>Vérifier le support du format par le client web</li>
<li>Vérifier que le fichier statique compressé existe localement</li>
<li>Envoi du fichier statique compressé.</li>
</ul>
</li>
</ol>
<h2 id="compression-brotli-local">Compression brotli local</h2>
<p>La compression de fichiers se fait simplement : <code>$ brotli -Z fichier</code><br>
qui produira un fichier supplémentaire portant l&rsquo;extension <code>br</code>. L&rsquo;option
<code>-Z</code> offre le meilleur taux de compression, par défaut.</p>
<p><em>Lire le manpage installé, pour plus d&rsquo;informations, si besoin… <code>$ man brotli</code></em></p>
<hr>
<p>Voici la fonction que j&rsquo;utilise dans le cadre de mon fichier <code>deploy</code> pour
mes fichiers créés avec Hugo :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">_gz()</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">cd</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">${dir_local}&#34;</span> <span style="color:#48b685">||</span> <span style="color:#48b685">exit</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">find</span> <span style="color:#48b685">.</span> <span style="color:#48b685">-type</span> <span style="color:#48b685">f</span> <span style="color:#48b685">-size</span> <span style="color:#48b685">+1024c</span> <span style="color:#48b685">-a</span> <span style="color:#48b685">\(</span> <span style="color:#48b685">\</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.css&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.eot&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.html&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.js&#34;</span> <span style="color:#48b685">\</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.otf&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.svg&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.ttf&#34;</span> <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.txt&#34;</span> <span style="color:#48b685">\</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">-o</span> <span style="color:#48b685">-name</span> <span style="color:#48b685">&#34;*.xml&#34;</span> <span style="color:#48b685">\</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">\)</span> <span style="color:#48b685">|</span> <span style="color:#48b685">while</span> <span style="color:#48b685">read</span> <span style="color:#48b685">-r</span> <span style="color:#48b685">line</span>; <span style="color:#5bc4bf">do</span> <span style="color:#48b685">echo</span> <span style="color:#48b685">&#34;Compress</span> <span style="color:#ef6155">${line}&#34;</span>; <span style="color:#5bc4bf">brotli</span> <span style="color:#48b685">-Z</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">${line}&#34;</span>; <span style="color:#5bc4bf">gzip</span> <span style="color:#48b685">-9</span> <span style="color:#48b685">-f</span> <span style="color:#48b685">&lt;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">${line}&#34;</span> <span style="color:#48b685">&gt;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">${line}.gz&#34;</span>; <span style="color:#5bc4bf">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">cd</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$ROOT&#34;</span> <span style="color:#48b685">||</span> <span style="color:#48b685">exit</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><p>Ainsi, si le fichier statique fait plus de 1024 octets - <em>choix totalement
arbitraire</em> - et que son extension est de type CSS, JS, JSON, HTML, SVG,
TXT, ou XML, ou des fichiers de fonts de type eot, otf, ou ttf, alors
la fonction compresse, dans un premier temps, au format brotli, suivi
d&rsquo;une compression au format gzip.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pourquoi compresser aussi au format gzip ?</p>
<p>Pour les clients web qui n&rsquo;ont pas la gestion du format brotli, cela permettra
d&rsquo;offrir un format de compression alternatif, reconnu généralement.</p>
<p>De même, la gestion du format brotli semble n&rsquo;être efficace qu&rsquo;avec l&rsquo;usage
du protocole <abbr title="HyperText Transfert Protocole Secure">HTTPS</abbr>
, même
si votre client web lui le gère.</p>
</div>

<h2 id="configuration-nginx">Configuration nginx</h2>
<p>Passons maintenant au paramètrage du serveur web nginx. Dans le contexte <code>server</code> :</p>
<ol>
<li>Dans un premier temps, nous déclarons une variable nommée <strong>$extension</strong> : <code>set $extension &quot;&quot;;</code></li>
<li>puis, nous vérifions le support de brotli par le client  web, pour affecter
la variable <code>$extension</code> qui nous servira ensuite :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$http_accept_encoding</span> ~ <span style="color:#48b685">br)</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">set</span> <span style="color:#ef6155">$extension</span> <span style="color:#48b685">.br</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ol start="2">
<li>dans un second temps, nous demandons à nginx de vérifier l&rsquo;existence
du fichier statique au format compressé :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(-f</span> <span style="color:#ef6155">$request_filename$extension</span><span style="color:#48b685">)</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">rewrite</span> <span style="color:#48b685">(.*)</span> <span style="color:#ef6155">$1$extension</span> <span style="color:#48b685">break</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ol start="3">
<li>ensuite, nous utilisons les déclarations de contexte <code>location</code> pour
délivrer le fichier statique demandé dans sa forme compressée. Par
exemple, pour un fichier CSS :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.css.br$</span> {
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Content-Encoding</span> <span style="color:#48b685">br</span>;
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">gzip</span> <span style="color:#ef6155">off</span>;
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">types</span> {}
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">text/css</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>Faire de même pour les autres formats de fichiers compressables, tels
que ceux cités ci-dessus.<br>
Remarquons :
<ul>
<li>l&rsquo;usage de la déclaration <code>gzip off;</code> puisque nous n&rsquo;avons pas besoin
à ce moment de ladite compression.</li>
<li>l&rsquo;ajout des entêtes HTTP nécessaires</li>
<li>et la déclaration du type de contenu lié au format de fichier délivré.</li>
</ul>
</li>
</ul>
<p>Voilà.</p>
<hr>
<p>Pour finir, je vous offre les deux fichiers de déclaration que j&rsquo;utilise
pour mon serveur nginx sous OpenBSD :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">set</span> <span style="color:#ef6155">$extension</span> <span style="color:#48b685">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$http_accept_encoding</span> ~ <span style="color:#48b685">br)</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">set</span> <span style="color:#ef6155">$extension</span> <span style="color:#48b685">.br</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(-f</span> <span style="color:#ef6155">$request_filename$extension</span><span style="color:#48b685">)</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">rewrite</span> <span style="color:#48b685">(.*)</span> <span style="color:#ef6155">$1$extension</span> <span style="color:#48b685">break</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.css.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">text/css</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># font file eot
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.eot.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/server/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">application/vnd.ms-fontobject</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.html.br</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">text/html</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.js.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">application/javascript</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.json.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">application/json</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># opentype font file
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.otf.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/server/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">font/opentype</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.svg.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">image/svg+xml</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># font file ttf
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.ttf.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/server/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">font/ttf</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.txt.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">text/plain</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">/*.xml.br$</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">include</span> <span style="color:#48b685">/etc/nginx/conf.d/brotli-infos.conf</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default_type</span> <span style="color:#48b685">text/xml</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">Content-Encoding</span> <span style="color:#48b685">br</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">Vary</span> <span style="color:#48b685">&#34;Accept-Encoding&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">gzip</span> <span style="color:#ef6155">off</span>;
</span></span></code></pre></div><hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li>Au cas où vous seriez intéressé par savoir comment faire avec le serveur
web natif <strong>httpd</strong> sous OpenBSD, lisez mon article 
<a class="inside" href="/fr/web/httpd/httpd-delivre-fichiers-compresses/" title="Lien interne vers l&#39;article : 'httpd : délivrer des fichiers statiques compressés (&#43; slowcgi)'">httpd : délivrer des fichiers statiques compressés (&#43; slowcgi)</a>

…</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment utiliser la compression brotli avec le server web nginx sous OpenBSD… pour des fichiers statiques]]></summary>
        <published>2020-08-20T12:35:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5ea2fb29-8613-30da-107d-c983c9d023d5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/acme-client-bad-exit/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD: acme-client: bad exit</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="acme-client" scheme="http://doc.huc.fr.eu.org/fr/tags/acme-client/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Sous OpenBSD depuis 6.1, pour la génération de certificats avec l&rsquo;autorité
de certification <strong>Let&rsquo;s Encrypt</strong>, nous avons intégré au système de base le
client acme, écrit en C, reconnu pour être sécurisé.</p>
<p>Je ne traiterais pas de la configuration, elle est très simple, et vraiment
bien <a href="/fr/sys/openbsd/acme-client-bad-exit/#documentations">documentée</a> dans le manpage ad hoc.</p>
<p>Ce mémo existe pour répertorier quoi faire dans le cas de sortie en erreur.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="bad-http-400">bad HTTP: 400</h3>
<p>































































































<abbr lang="en" title="Too Long; Did&#39;nt Read">TL;DR</abbr>
















 : Le client acme n&rsquo;arrive pas à se connecter à votre
serveur web. Dans les faits, il faut en passer par une investigation et une
explication un peu plus poussée…</p>
<p><strong>Investigation :</strong></p>
<p>Par exemple, voici la fin du message verbeux d&rsquo;acme :</p>
<pre tabindex="0"><code># acme-client -v mydomain.tld
(…)
acme-client: challenge, token: L8dcjbmFhbE6N2GtSKxEi9yzhR888oSdBdgzt7GnJbc, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/6581640382/2HdrCw, status: -1
(…)
acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/6460247699/ixiI9A: bad HTTP: 400
acme-client: transfer buffer: [{ &#34;type&#34;: &#34;urn:ietf:params:acme:error:malformed&#34;, &#34;detail&#34;: &#34;Unable to update challenge :: authorization must be pending&#34;, &#34;status&#34;: 400 }] (144 bytes)
acme-client: bad exit: netproc(70635): 1
</code></pre><p>Le réflexe à avoir est de basculer en mode doublement verbeux, ce qui nous
donnera plus de détail :</p>
<pre tabindex="0"><code># acme-client -vv mydomain.tld
(…)
acme-client: transfer buffer: [{ &#34;identifier&#34;: { &#34;type&#34;: &#34;dns&#34;, &#34;value&#34;: &#34;www.mydomain.tld&#34; }, &#34;status&#34;: &#34;invalid&#34;, &#34;expires&#34;: &#34;2020-08-24T22:24:39Z&#34;, &#34;challenges&#34;: [ { &#34;type&#34;: &#34;http-01&#34;, &#34;status&#34;: &#34;invalid&#34;, &#34;error&#34;: { &#34;type&#34;: &#34;urn:ietf:params:acme:error:connection&#34;, &#34;detail&#34;: &#34;Fetching http://mydomain.tld/.well-known/acme-challenge/xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg: Connection refused&#34;, &#34;status&#34;: 400 }, &#34;url&#34;: &#34;https://acme-v02.api.letsencrypt.org/acme/chall-v3/6603509164/7d1MkA&#34;, &#34;token&#34;: &#34;xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg&#34;, &#34;validationRecord&#34;: [ { &#34;url&#34;: &#34;http://www.mydomain.tld/.well-known/acme-challenge/xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg&#34;, &#34;hostname&#34;: &#34;www.mydomain.tld&#34;, &#34;port&#34;: &#34;80&#34;, &#34;addressesResolved&#34;: [ &#34;88.136.16.221&#34;, &#34;2001:470:cc33::3&#34; ], &#34;addressUsed&#34;: &#34;2001:470:cc33::3&#34; }, { &#34;url&#34;: &#34;http://www.mydomain.tld/.well-known/acme-challenge/xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg&#34;, &#34;hostname&#34;: &#34;www.mydomain.tld&#34;, &#34;port&#34;: &#34;80&#34;, &#34;addressesResolved&#34;: [ &#34;88.136.16.221&#34;, &#34;2001:470:cc33::3&#34; ], &#34;addressUsed&#34;: &#34;88.136.16.221&#34; }, { &#34;url&#34;: &#34;http://mydomain.tld/.well-known/acme-challenge/xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg&#34;, &#34;hostname&#34;: &#34;mydomain.tld&#34;, &#34;port&#34;: &#34;80&#34;, &#34;addressesResolved&#34;: [ &#34;88.136.16.221&#34;, &#34;2001:470:cc33::3&#34; ], &#34;addressUsed&#34;: &#34;2001:470:cc33::3&#34; } ] } ] }] (1712 bytes)
acme-client: challenge, token: xCefC0pD3W1VRLeWVYHmYmJj1Bf06G1hoskXdN1xIEg, uri: https://acme-v02.api.letsencrypt.org/acme/chall-v3/6603509164/7d1MkA, status: -1
(…)
acme-client: https://acme-v02.api.letsencrypt.org/acme/chall-v3/6603509164/7d1MkA: bad HTTP: 400
acme-client: transfer buffer: [{ &#34;type&#34;: &#34;urn:ietf:params:acme:error:malformed&#34;, &#34;detail&#34;: &#34;Unable to update challenge :: authorization must be pending&#34;, &#34;status&#34;: 400 }] (144 bytes)
acme-client: bad exit: netproc(37360): 1
</code></pre><p><strong>Explications</strong></p>
<p>Au dessus de la ligne terminant par <code>status: -1</code>, on remarque une nouvelle
ligne. Cette ligne nous informe :</p>
<ul>
<li>
<p>que le status est <code>invalid</code>,</p>
</li>
<li>
<p>que la connexion a été refusée : <code>Connection refused</code>,</p>
</li>
<li>
<p>qu&rsquo;elle a été fermée par le client : <code>status: 400</code>,</p>
</li>
<li>
<p>qu&rsquo;elle a échoué sur la connexion de l&rsquo;adresse IPv6 du serveur :
<code>&quot;addressUsed&quot;: &quot;2001:470:cc33::3&quot;</code></p>
</li>
</ul>
<p>En fait, acme-client informe qu&rsquo;il n&rsquo;arrive pas à se connecter sur le serveur
à l&rsquo;adresse IPv6. La première chose à s&rsquo;assurer est que le serveur web
soit joignable sur votre adresse IPv6 !</p>
<p>Il peut y avoir diverses raisons pour lesquelles votre serveur web ne soit
pas joignable sur IPv6 :</p>
<ul>
<li>
<p>assurez-vous que l&rsquo;adresse IPv6 réponde à la commande <code>ping6</code>, puis…</p>
</li>
<li>
<p>l&rsquo;oubli de configuration du serveur lui-même… vérifiez que vous avez bien
autorisé la connexion sur IPv6.</p>
<ul>
<li>
<p>pour httpd : <code>listen on votre-adresse-ipv6 port 80</code></p>
</li>
<li>
<p>pour nginx : <code>listen [::]:80;</code></p>
</li>
</ul>
</li>
<li>
<p>le pare-feu local 








































































<abbr lang="en" title="Packet Filter">PF</abbr>







































 qui n&rsquo;autorise pas la connexion sur les
ports 































<abbr lang="en" title="HyperText Transfer Protocol">HTTP</abbr>
















































































, voire 
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































, sur l&rsquo;adresse 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>










































































du serveur : <br>
<code>pass in quick on egress inet6 proto tcp to votre-adresse-ipv6 port 80 flags S/SA modulate state</code></p>
</li>
<li>
<p>Avez-vous en amont un pare-feu ? vérifiez que vos règles de parefeu redirigent
bien le flux HTTP(S) vers votre serveur web…</p>
</li>
</ul>
<p>Une manière de s&rsquo;en assurer est d&rsquo;utiliser un scanner de port sur 






































<abbr lang="en" title="Internet Protocol v6">IPv6</abbr>









































































,
par exemple celui de <a href="http://www.ipv6scanner.com/cgi-bin/main.py" rel="external">ipv6scanner.com</a>.
Si le scanner vous dit qu&rsquo;aucun port correspond n&rsquo;est ouvert, cherchez
profondément la raison…</p>
<p>Dans cet exemple, le serveur ne répondait pas lors de l&rsquo;interrogation sur
son adresse IPv6. Le <code>status 400</code> peut très bien être provoqué sur l&rsquo;adresse
IPv4 du serveur. Appliquez le même raisonnement pour vous assurez que votre
serveur soit joignable sur son adresse 





































<abbr lang="en" title="Internet Protocol v4">IPv4</abbr>










































































.</p>
<p>Ceci est une des raisons pour lesquelles acme-client peut retourner un statut
d&rsquo;erreur 400. À chaque fois, il faut analyser profondément les informations
retournées.</p>
<h3 id="orderstatus--1">order.status -1</h3>
<p>Le client acme restitue de manière sybilline ce message :</p>
<pre tabindex="0"><code># acme-client -v mydomain.tld
(…)
acme-client: order.status -1
acme-client: bad exit: netproc(27643): 1
</code></pre><p>Là, il peut y avoir de multiples raisons qui empêche tout simplement le
client acme de discuter avec votre serveur web.</p>
<p>Le propos est de vérifier qu&rsquo;aucune écriture de la configuration du serveur
n&rsquo;empêche la lecture dans le répertoire de challenge acme.</p>
<p>Exemples pouvant générer :</p>
<ul>
<li>pour nginx, une simple écriture telle que la suivante peut empêcher l&rsquo;accès
au répertoire de challenge acme :</li>
</ul>
<pre tabindex="0"><code>location ~ /\. {
    access_log off;
    log_not_found off;
    deny all;
}
</code></pre><ul>
<li>concernant relayd, des règles filtrantes les méthodes de connexion peuvent
empêcher le bon fonctionnement…</li>
</ul>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/acme-client" title="Page du Manuel OpenBSD pour : acme-client">acme-client</a>
, 
<a class="man" href="https://man.openbsd.org/acme-client.conf.5" title="Page du Manuel OpenBSD pour : acme-client.conf">acme-client.conf(5)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre des erreurs de sortie du client acme sous OpenBSD…]]></summary>
        <published>2020-08-19T03:27:17+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:7d6a0b32-fe4c-3e76-b83c-504777bf644f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/epson-mfp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Installer et configurer une imprimante Epson MFP (Cups)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <category term="MFP" scheme="http://doc.huc.fr.eu.org/fr/tags/mfp/" />
        <category term="Cups" scheme="http://doc.huc.fr.eu.org/fr/tags/cups/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Cet article montre comment installer et utiliser une imprimante {{ abbr2 MFP &gt;}}
de marque Epson, sous OpenBSD, avec Cups.</p>
<p>Si votre imprimante gère le protocole <a href="http://global.epson.com/innovation/universal_printing/driver_library.html" rel="external">ESC/P-R</a>,
continuez la lecture… sinon au-revoir !</p>
<p>De même, ce tutoriel ne montre pas la configuration par connexion USB, mais
en mode réseau.</p>
<p>Imprimantes testées :</p>
<ul>
<li>Stylus Office <strong><a class="inside" href="/fr/sys/openbsd/epson-bx525wd/" title="Lien interne vers l&#39;article : 'Epson Stylus Office BX525WD / OpenBSD'">BX525WD</a>
</strong> - OpenBSD 6.0 ⇒ 6.6</li>
<li>EcoTank <strong><a class="inside" href="/fr/sys/openbsd/epson-ecotank-et-3700/" title="Lien interne vers l&#39;article : 'Epson EcoTank ET-3700 / OpenBSD'">ET-3700</a>
</strong> - OpenBSD 6.7 ⇒ actuellement</li>
</ul>
<h2 id="installation">Installation</h2>
<h3 id="avahi">Avahi</h3>
<p>La MFP peut être détectée de manière automatique sur votre réseau, grâce
au protocole DNSSD, si et seulement si vous installez le paquet
<strong><a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">avahi</a>
</strong>
Celui-ci nécessite que le service <strong>messagebus</strong> soit actif.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Autant la détection de la MFP se fait sans soucis, autant je ne suis jamais
arrivé à l&rsquo;utiliser ainsi.</p>
<p><strong>Avahi</strong> n&rsquo;est pas strictement nécessaire.</p>
</div>

<h3 id="cups">Cups</h3>
<p>Commencez par installer <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
 !</p>
<hr>
<p>Depuis OpenBSD 6.2, les binaires <code>lpq</code>, <code>lpr</code>, et <code>lprm</code> ne sont plus liés
symboliquement à <code>/usr/bin</code>. Il est nécessaire de les utiliser en les préfixant
de <code>/usr/local/bin/</code>.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Pensez à éditer votre fichier <code>~/.kshrc</code>, afin de créer des alias qui vous
seront utiles, en ajoutant le code suivant :</p>
<p><code>for i in lpq lpr lprm; do alias $i=/usr/local/bin/$i; done</code></p>
</div>

<h4 id="cups-fichiers-ppd">Cups: Fichiers PPD</h4>
<ul>
<li><strong>BW525WD</strong> : choisir le fichier BX525WD ou BX535WD</li>
<li><strong>ET-3700</strong> : copiez le fichier <code>/usr/local/share/ppd/epson-inkjet-printer-escpr/Epson-ET-4700_Series-epson-escpr-en.ppd</code>
vers votre répertoire <code>~/Downloads</code> puis indiquez-le à l&rsquo;interface Web de Cups.</li>
</ul>
<h3 id="pilote-epson">Pilote Epson</h3>
<p>Dans un premier temps, il est nécessaire
d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 le
paquet <strong>epson-inkjet-printer-escpr</strong>.</p>
<p>Les paquets <strong>foomatic</strong> et <strong>gutenprint</strong> peuvent à être utile à la reconnaissance
du périphérique.</p>
<h3 id="sane">Sane</h3>
<p>Pour pouvoir scanner, il est nécessaire d&rsquo;installer le logiciel <strong>sane</strong> : <br>
<code>:# sane-backends xsane</code></p>
<p>Il sera accessible depuis le menu &ldquo;Graphisme&rdquo; &gt; &ldquo;Xsane&rdquo;.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="protocoles-réseaux">Protocoles réseaux</h3>
<p>De préférence, choisir le protocole Unix <strong>lpd</strong>, c&rsquo;est celui qui fonctionne le
mieux… <br>
Tel que : <code>lpd://adr_ip/PASSTHRU</code></p>
<p>Il est possible d&rsquo;imprimer aussi sur ces autres protocoles :</p>
<ul>
<li><strong>ipp</strong>, <strong>ipps</strong> : <code>ipp://adr_ip:631/ipp/print</code> ou <code>ipps://adr_ip:631/ipp/print</code></li>
<li><strong>http</strong>, <strong>https</strong> : <code>http://adr_ip:631/ipp/print</code> ou <code>https://adr_ip:631/ipp/print</code></li>
<li><strong>AppSocket/HP JetDirect</strong> : <code>socket://adr_ip:9100</code></li>
</ul>
<p>Les versions <strong>ipps</strong> et <strong>https</strong> nécessitent une configuration plus
poussée, non abordée ici.</p>
<p>Théoriquement, Cups permet aussi d&rsquo;imprimer via Samba, mais je n&rsquo;ai pas testé.</p>
<h3 id="scanner-bw525wd">Scanner BW525WD</h3>
<ol>
<li>
<p>Dans un premier temps, il faut modifier le fichier de configuration
<code>/etc/sane.d/dll.conf</code> pour y ajouter le mot clé <strong>epkowa</strong>.</p>
</li>
<li>
<p>Ensuite, il est nécessaire de modifier le fichier de configuration
<code>/etc/sane.d/epkowa.conf</code> pour préciser : <code>net adr_ip 1865</code></p>
</li>
</ol>
<p>Il est probable que le fichier <strong>epkowa.conf</strong> ne soit pas disponible ;
je vous propose cette version par défaut à configurer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># epkowa.conf -- sample configuration for the EPKOWA SANE backend</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Copyright (C) 2004, 2008, 2009  Olaf Meeuwissen</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See sane-epkowa(5), sane-usb(5) and sane-scsi(5) for details.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Detect all devices supported by the backend.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># If you don&#39;t have a SCSI device, you can comment out the &#34;scsi&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># keyword.  Similarly for the other keywords.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">usb</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">scsi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For any USB scanner not known to the backend (yet), you may, at your</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># own peril(!!), force the backend to recognise and use it via libusb.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># You can do so by the following configuration command:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   usb &lt;USB vendor ID&gt; &lt;USB product ID&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># SEIKO EPSON&#39;s USB vendor ID is &#39;0x04b8&#39; (without quotes).  In order</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># to find the USB product ID, use lsusb(1).</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># A sample configuration for the Epson Perfection 1650 (Epson GT-8200),</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># which has a product ID of 0x0110, would look as follows:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#usb 0x04b8 0x0110</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For SCSI devices not detected, you can add an entry like:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   scsi EPSON GT-20000</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># where the GT-20000 bit corresponds to the SCSI model information as</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># shown in the output of dmesg(1) or in the /var/log/kern.log file.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Network attached devices may be made to work by first installing the</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># (non-free) iscan-network-nt package and then adding configuration lines</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># as per information below.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For each network attached device, you must add an entry as follows:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   net &lt;IP-address|hostname&gt; [port-number]</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Ask your network administrator for the device&#39;s IP address or check</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># for yourself on the panel (if it has one).  The port-number is very</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># optional and defaults to 1865.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Note that network attached devices are not queried unless configured</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># in this file.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Examples:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net 192.16.136.2 1865</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net 10.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net scanner.mydomain.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Some backend behaviour can be customized by using the option keyword</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># followed by an option name, as shown below.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option &lt;option-name&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Currently available options:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Makes the automatic document feeder the default document source</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#option prefer-adf</span>
</span></span></code></pre></div><h3 id="scanner-et-3700">Scanner ET-3700</h3>
<p><span class="red">La partie scanner n'est pas encore gérée</span>
.
Les scanners de la série EcoTank sont reconnus en tant que <a href="http://www.sane-project.org/lists/sane-backends-external.html#S-UTSUSHI" rel="external">backend externe</a>
à SANE, par le projet de pilote nommé <strong>utsushi</strong>.</p>
<p>Le dépôt officiel du projet utsushi : <a href="https://gitlab.com/utsushi/utsushi" rel="external">https://gitlab.com/utsushi/utsushi</a></p>
<p>Gageons que dans un futur procher, le projet Sane intégrera ce pilote,
ce qui devrait ensuite permettre l&rsquo;usage de la partie scanner.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment configurer une imprimante multifunction de marque Epson sous OpenBSD avec Cups]]></summary>
        <published>2020-07-25T17:39:49+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a099c459-9a09-45e8-d2b8-8b8584351f67</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/epson-ecotank-et-3700/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Epson EcoTank ET-3700 / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Testée sur OpenBSD stable : 6.7</p>
<h2 id="gestion-de-limpression">Gestion de l&rsquo;impression</h2>
<p>La partie impression fonctionne très bien…</p>
<p>Après avoir <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installé</a>

le paquet <code>epson-inkjet-printer-escpr</code>, copiez le fichier
<code>/usr/local/share/ppd/epson-inkjet-printer-escpr/Epson-ET-4700_Series-epson-escpr-en.ppd</code>
vers votre répertoire <code>~/Downloads</code>.</p>
<p>Indiquez à Cups d&rsquo;installer le fichier PPD en cliquant sur le bouton
[ Browse… ] au moment du choix de celui-ci.</p>
<h3 id="protocoles-de-connexion-supportés">Protocoles de connexion supportés</h3>
<p>Les protocoles de connexion suivants sont supportés :</p>
<ul>
<li><strong>lpd</strong> : <code>lpd://adr_ip/PASSTHRU</code></li>
<li><strong>ipp</strong>, <strong>ipps</strong> : <code>ipp://adr_ip:631/ipp/print</code>&gt; ou <code>ipps://adr_ip:631/ipp/print</code></li>
<li><strong>http</strong>, <strong>https</strong> : <code>http://adr_ip:631/ipp/print</code> ou <code>https://adr_ip:631/ipp/print</code></li>
<li><strong>AppSocket/HP JetDirect</strong> : <code>socket://adr_ip:9100</code></li>
</ul>
<h4 id="protocole-de-connexion-non-testé">Protocole de connexion non testé</h4>
<ul>
<li><strong>Windows Printer via SAMBA</strong> : <code>smb://adr_ip/printer</code></li>
</ul>
<h3 id="protocoles-de-connexion-non-supportés">Protocoles de connexion non supportés</h3>
<ul>
<li><strong>dnssd</strong> : Si le paquet <a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi</a>

est installé, elle est vue par le biais du protocole DNS-SD, elle
s&rsquo;installera, mais après lors d&rsquo;impression, cups n&rsquo;arrive pas à
discuter avec…</li>
</ul>
<hr>
<p>Pensez à <a class="inside" href="/fr/sys/openbsd/rcctl/#red%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">redémarrer</a>

le service <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
 !</p>
<h2 id="gestion-du-scanner">Gestion du scanner</h2>
<p>La partie scanner n&rsquo;est pas encore gérée. Les scanners de la série
EcoTank sont reconnus pour être pris en charge par la partie de
<a href="http://www.sane-project.org/lists/sane-backends-external.html#S-UTSUSHI" rel="external">backend externe utsushi</a>
au projet SANE.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Support de l&#39;imprimante MFP, de marque Epson, modèle EcoTank ET63700, sous OpenBSD]]></summary>
        <published>2020-06-20T16:57:43+02:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:dbd1a205-82c4-831c-394b-16247bb06ea9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/unstable-sid/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Gérer Sid</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Unstable" scheme="http://doc.huc.fr.eu.org/fr/tags/unstable/" />
        <category term="Sid" scheme="http://doc.huc.fr.eu.org/fr/tags/sid/" />
        <category term="Devuan" scheme="http://doc.huc.fr.eu.org/fr/tags/devuan/" />
        <category term="Ceres" scheme="http://doc.huc.fr.eu.org/fr/tags/ceres/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un petit mémoriel pour décrire comment gérer régulièrement une Debian Sid.
Ceci est aussi valable pour une Devuan Ceres.</p>
<p>C&rsquo;est plus du &ldquo;Trucs &amp; Astuces&rdquo;, car je risque fort de ne pas rentrer dans
les détails, mais plutôt de préciser les étapes nécessaires à la gestion
d&rsquo;une version dite &ldquo;Unstable&rdquo; de Debian, ou Devuan.</p>
<h2 id="installation">Installation</h2>
<p>Je ne décrirais pas le processus d&rsquo;installation. Si vous avez déjà installé
une Debian/Devuan, vous êtes certainement déjà familier avec celui-ci.
Si ce n&rsquo;est pas le cas, voyez la section <a href="/fr/sys/debian/unstable-sid/#documentation">Documentation</a>
où vous trouverez des informations utiles.</p>
<h3 id="install-sid">Install Sid</h3>
<p>Pour installer Sid, le plus simple est de télécharger l&rsquo;image <strong>mini.iso</strong>.
Cette version minimale de Debian Sid est mise à jour régulièrement.</p>
<p>Pour :</p>
<ul>
<li>amd64 : <a href="http://ftp.debian.org/debian/dists/sid/main/installer-amd64/current/images/netboot/mini.iso" rel="external">http://ftp.debian.org/debian/dists/sid/main/installer-amd64/current/images/netboot/mini.iso</a></li>
<li>i386 : <a href="http://ftp.debian.org/debian/dists/sid/main/installer-i386/current/images/netboot/mini.iso" rel="external">http://ftp.debian.org/debian/dists/sid/main/installer-i386/current/images/netboot/mini.iso</a></li>
</ul>
<p>Pour les autres architectures, parcourez l&rsquo;arborescence correspondante à
la vôtre dans le répertoire ftp suivant : <br>
<a href="http://ftp.debian.org/debian/dists/sid/main/" rel="external">http://ftp.debian.org/debian/dists/sid/main/</a></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">De temps à autre, il est possible que l&rsquo;installateur échoue dans l&rsquo;installation
de la Sid. Dans ce cas-là, il faudra attendre une nouvelle version de l&rsquo;image ISO.
<em>Ou, essayez l&rsquo;un des projets ci-dessous.</em></div>

<hr>
<p>Pour information, il existe quelques communautés différentes qui proposent aussi
Debian Sid, déjà packagée, prête à être installé :</p>
<ul>
<li><a href="https://antixlinux.com/updated-antix-sid-iso-files-available/" rel="external">antiX-Sid</a> :
une Debian Sid, sans systemd, principalement pour PC léger, ou très ancien</li>
<li><a href="https://siduction.org/" rel="external">Siduction</a></li>
<li><a href="https://xebian.org/" rel="external">Xebian</a></li>
</ul>
<p><em>Par expérience, préférez la Xebian… elle fournit par défaut les <a href="/fr/sys/debian/unstable-sid/#outils-apt">outils apt</a>
nécessaires. De plus, l&rsquo;image ISO est plus souvent générée.</em></p>
<p>Quoiqu&rsquo;il en soit les conseils de <a href="/fr/sys/debian/unstable-sid/#gestion">gestion</a> que vous trouverez
ci-dessous, sont absolument valables. Tenez en compte !</p>
<h3 id="install-ceres">Install Ceres</h3>
<p>Pour la Devuan Ceres, le plus simple est de partir de l&rsquo;<a href="https://devuan.org/" rel="external">installation de la
stable actuelle</a>, puis de modifier votre fichier <code>sources.list</code> pour qu&rsquo;il
contienne à minima cette ligne : <br>
<code>deb http://deb.devuan.org/merged ceres main non-free contrib</code></p>
<p><em>Ce qui signifie de commenter celles de votre précédente installation,
voire de les supprimer</em>.</p>
<p>Pour le faire proprement : <code># apt edit-sources</code></p>
<p>Puis mettez à jour les dépôts et faites une mise à niveau :</p>
<pre tabindex="0"><code>:# apt update
:# apt full-upgrade
</code></pre><h3 id="outils-apt">Outils apt</h3>
<p>Les outils supplémentaires à installer <strong>ABSOLUMENT</strong> sont des outils
complémentaires à l&rsquo;outil <code>apt</code> :</p>
<ul>
<li><code>apt-listbugs</code> : outil qui lors d&rsquo;une mise à jour vous avertira à-propos
duquel logiciel a un bogue plus ou moins critique. Cet outil est <strong>PRIMORDIAL</strong>.</li>
<li><code>apt-listchanges</code> : outil qui vous informera après la mise à jour, des
changements importants fait sur untel logiciel.</li>
<li><code>needrestart</code> : outil qui permet de savoir quel service doit absolument
être redémarré après une mise à jour. Pas nécessaire, mais utile.</li>
<li><code>package-update-indicator</code> : outil de suivi et notification de la disponibilité
de paquets mis à jour. Pas nécessaire, mais utile.</li>
</ul>
<p><em>Si vous avez choisi d&rsquo;installer la Xebian, les deux premiers outils sont
fournis, par défaut.</em></p>
<h2 id="gestion">Gestion</h2>
<p>Lorsque vous faites une mise à jour, s&rsquo;il y a des bogues plus ou moins
critique, du fait d&rsquo;avoir installé l&rsquo;outil <strong>apt-listbugs</strong>, <strong>apt</strong> vous
avertira que tel logiciel a tel bogue, ayant tel niveau de criticité.</p>
<p>Le plus simple est, si vous avez un doute, que vous ne comprenez pas en quoi
ce bogue consiste, comment il impacte le système, alors répondez <strong>ABSOLUMENT</strong>
par l&rsquo;appui sur la touche <kbd>P</kbd> !</p>
<p>Cela &ldquo;épinglera&rdquo; le logiciel en question, empêchant sa mise à jour jusqu&rsquo;à
une future mise à jour qui aura corrigé le bogue en question et vous permettra
à ce moment futur de le mettre à jour sans aucun soucis.</p>
<p>Tout épingleage sera enregistré dans le fichier
<code>/etc/apt/preferences.d/apt-listbugs</code>.</p>
<p>L&rsquo;impact : à chaque logiciel, que vous aurez figé en état &ldquo;Pin&rdquo;, il vous
faudra arrêter ensuite la mise à jour en appuyant ensuite sur la touche
<kbd>N</kbd>… <br>
Puis relancer la mise à jour normalement.</p>
<p>Les logiciels &ldquo;étiquettés&rdquo;, ainsi par vos soins, ne vous seront plus soumis
à l&rsquo;analyse, et attendront une future mise à jour corrigeant le(s) bogue(s)
en question.</p>
<p>⇒ À partir du moment où vous avez installé <strong>apt-listbugs</strong>, <strong>apt</strong> vous
avertira aussi lors d&rsquo;une installation logicielle. S&rsquo;il y a un bogue critique
qui concerne le logiciel que vous cherchez à installer sur votre architecture,
il est certainement prudent d&rsquo;en tenir compte ; si cela concerne une autre
architecture, ne vous tracassez pas du bogue en question, et faites votre
installation demandée/nécessaire. <br>
Dans le cas où vous épinglez le logiciel lors de l&rsquo;installation, à cause
d&rsquo;un bogue critique, vous ne pourrez donc pas installer le logiciel ; il
vous faudra attendre une future mise à jour de celui-ci.</p>
<p>C&rsquo;est un dilemne : à vous de faire votre choix. Étant donné que les messages
d&rsquo;avertissements sont en anglais, il peut en effet être délicat de les comprendre.
Ne faites pas l&rsquo;impasse sur un message que vous ne comprenez pas, en prenant
le risque d&rsquo;installer ou de mettre à jour un logiciel.</p>
<p>Posez des questions au-travers des différentes <a href="/fr/sys/debian/unstable-sid/#communaute">communautés</a>,
qui généralement, seront capables de vous aider de manière adéquate.</p>
<p>⇒ Si <strong>apt-listchanges</strong> vous avertit d&rsquo;un changement précis, tenez-en compte.
À ce propos, si vous avez configuré votre système pour envoyer des courriels,
vous recevrez un courriel vous informant desdits changements.</p>
<p>⇒ Pensez à redémarrer <strong>absolument</strong> votre machine si un nouveau noyau a été
installé. Malheureusement, parfois un nouveau noyau ne vous permettra pas
d&rsquo;utiliser correctement votre matériel, cela peut en effet arriver. Il vous
faudra veiller à garder et redémarrer sur un noyau précédent fonctionnel.</p>
<p>⇒ <strong>needrestart</strong> vous avertira de redémarrer tel ou tel service ; parfois,
ce sera votre session utilisateur qu&rsquo;il faudra simplement redémarrer.</p>
<p>⇒ Régulièrement, utilisez l&rsquo;option <code>autoremove</code> de l&rsquo;outil <strong>apt</strong> afin
de supprimer les dépendances qui ne seraient plus nécessaires à votre
système suite à vos différentes mises à jours. <em>Lire à ce propos le chapitre
<a href="/fr/sys/debian/unstable-sid/#gestion-dautoremove">correspondant</a>.</em></p>
<h3 id="gestion-hebdomadaire">Gestion Hebdomadaire</h3>
<p>Une fois par semaine, de préférence le Lundi - <em>l&rsquo;expérience m&rsquo;ayant appris
que c&rsquo;est le jour le moins critique, dans le sens où je n&rsquo;ai jamais planté
une mise à jour d&rsquo;une Sid ce jour-là ; par contre, cela m&rsquo;est arrivé sur
d&rsquo;autres jours de la semaine</em>.</p>
<p>Ce jour-là, utilisez juste l&rsquo;option <code>upgrade</code> à l&rsquo;outil <code>apt</code>.</p>
<h3 id="gestion-mensuelle">Gestion Mensuelle</h3>
<p>Une fois par mois, <strong>ceci est un impératif</strong> - <em>qui peut être fait une fois
par semaine, mais généralement peu utile</em>, utilisez l&rsquo;option <code>full-upgrade</code>
de l&rsquo;outil <code>apt</code>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Prenez conscience que l&rsquo;usage de l&rsquo;option <code>full-upgrade</code> peut avoir pour
conséquence la suppression de certains logiciels installés, qui ne seront
peut-être pas réinstallables par la suite.</div>

<h3 id="gestion-dautoremove">Gestion d&rsquo;autoremove</h3>
<p>Parfois l&rsquo;outil <code>apt</code> peut vous informer d&rsquo;un certain nombre de logiciels
qui n&rsquo;ont plus de dépendances utiles et qui peuvent être supprimés avec
l&rsquo;option <code>autoremove</code>.</p>
<p>Ce sera particulièrement le cas lorsque vous aurez utiliser l&rsquo;option
<code>full-upgrade</code> pour mettre à jour votre version <strong>Unstable</strong>.</p>
<p>Si vous ne voulez pas que apt vous supprime particulièrement certains des
logiciels nommés dont vous pouvez avoir besoin, il faudra utiliser l&rsquo;outil
<code>apt-mark</code> au cas par cas en utilisant l&rsquo;option <code>manual</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ apt-mark manual nom-logiciel
</span></span></code></pre></div><p>Ensuite, une fois les logiciels marqués, vous pourrez utiliser l&rsquo;option <code>autoremove</code>
avec l&rsquo;outil <code>apt</code>.</p>
<p>Il est utile de lire le manpage : <br>
<code>man 8 apt-mark</code></p>
<h3 id="dépannage">Dépannage</h3>
<p>⇒ Lire les journaux liés à l&rsquo;activité d&rsquo;apt, ils sont dans <code>/var/log/apt</code>
et se nomme <code>history</code> et <code>term</code>. Le deuxième nécessite les droits admins
même pour la lecture, et reprend l&rsquo;historique de l&rsquo;activité tel qu&rsquo;il est
affiché dans le terminal/la console.</p>
<p>⇒ Pour savoir quels paquets sont épinglés, il y a deux manières :</p>
<ul>
<li>l&rsquo;utilisation de l&rsquo;outil <code>apt-cache</code> et de son option <code>policy</code>, tel que :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>Fichiers du paquet :
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">100</span> /var/lib/dpkg/status
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">a</span><span style="color:#5bc4bf">=</span>now
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/non-free i386 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>non-free,b<span style="color:#5bc4bf">=</span>i386
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/non-free amd64 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>non-free,b<span style="color:#5bc4bf">=</span>amd64
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/contrib i386 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>contrib,b<span style="color:#5bc4bf">=</span>i386
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/contrib amd64 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>contrib,b<span style="color:#5bc4bf">=</span>amd64
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/main i386 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>main,b<span style="color:#5bc4bf">=</span>i386
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">500</span> http://deb.devuan.org/merged ceres/main amd64 Packages
</span></span><span style="display:flex;"><span>     release <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span>1.0.0,o<span style="color:#5bc4bf">=</span>Devuan,a<span style="color:#5bc4bf">=</span>unstable,n<span style="color:#5bc4bf">=</span>ceres,l<span style="color:#5bc4bf">=</span>Devuan,c<span style="color:#5bc4bf">=</span>main,b<span style="color:#5bc4bf">=</span>amd64
</span></span><span style="display:flex;"><span>     origin deb.devuan.org
</span></span><span style="display:flex;"><span>Paquets épinglés :
</span></span><span style="display:flex;"><span>     libigdgmm12 -&gt; 22.0.2+ds1-1 avec la priorité <span style="color:#f99b15">30000</span>
</span></span><span style="display:flex;"><span>     libigdgmm12:i386 -&gt; 22.0.2+ds1-1 avec la priorité <span style="color:#f99b15">30000</span>
</span></span></code></pre></div><p><em>Remarquez la section &ldquo;<strong>Paquets épinglés :</strong>&rdquo; en fin d&rsquo;invite.</em></p>
<ul>
<li>et/ou afficher le fichier d&rsquo;épingles
<code>/etc/apt/preferences.d/apt-listbugs</code>.</li>
</ul>
<p>⇒ Parfois du fait d&rsquo;avoir épinglé un ou plusieurs logiciels, cela rend
impossible l&rsquo;installation d&rsquo;un autre logiciel avec un ou plusieurs messages
d&rsquo;erreurs lors de la tentative d&rsquo;installation, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Lecture des listes de paquets…
</span></span><span style="display:flex;"><span>Construction de l<span style="color:#48b685">&#39;arbre des dépendances…
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Lecture des informations d&#39;</span>état…
</span></span><span style="display:flex;"><span>Calcul de la mise à jour…
</span></span><span style="display:flex;"><span>Certains paquets ne peuvent être installés. Ceci peut signifier
</span></span><span style="display:flex;"><span>que vous avez demandé l<span style="color:#48b685">&#39;impossible, ou bien, si vous utilisez
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">la distribution unstable, que certains paquets n&#39;</span>ont pas encore
</span></span><span style="display:flex;"><span>été créés ou ne sont pas sortis d<span style="color:#48b685">&#39;Incoming.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">L&#39;</span>information suivante devrait vous aider à résoudre la situation :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Les paquets suivants contiennent des dépendances non satisfaites :
</span></span><span style="display:flex;"><span> linux-headers-5.16.0-3-amd64 : Dépend : linux-compiler-gcc-11-x86
</span></span><span style="display:flex;"><span>E: Impossible de corriger les problèmes, des paquets défectueux sont en mode <span style="color:#48b685">&#34;garder en l&#39;état&#34;</span>.
</span></span></code></pre></div><ol>
<li>Essayez d&rsquo;installer le paquet mentionné après le terme &ldquo;Depend :&rdquo;.</li>
<li>Parfois il sera nécessaire de supprimer/renommer le fichier de
preférences relatif à apt-listbugs, puis de retenter l&rsquo;installation qui
avertira très certainement que le paquet dépendant est en défaut… <br>
à chacun d&rsquo;analyser les erreurs remontées par apt-listbugs, pour décider
si le paquet en défaut peut quand même être installé, ce qui vous permettra
d&rsquo;installer le logiciel/paquet désiré.</li>
</ol>
<h2 id="communauté">Communauté</h2>
<p>N&rsquo;oubliez pas que leur coup de main est bénévole, souvent anonyme, alors
soyez le plus descriptif possible, fournissez une <strong>EXACTE</strong> copie du message
en n&rsquo;oubliant pas de décrire sur quelle architecture vous installez ou
mettez à jour tel logiciel !</p>
<p>Plus vous serez précis, plus vous serez agréable, et plus vous aurez des
chances d&rsquo;être aidé. Et surtout, n&rsquo;attendez pas <strong>ET</strong> n&rsquo;exigez <strong>JAMAIS</strong>
qu&rsquo;on vous aide absolument.</p>
<p>Soyez amical, cordial, agréable - même si la réponse ne vous plaît/convient pas.</p>
<ul>
<li>Debian
<ul>
<li>Pour débutants : <a href="https://debian-facile.org" rel="external">https://debian-facile.org</a></li>
<li>Pour confirmés : <a href="https://www.debian-fr.org" rel="external">https://www.debian-fr.org</a></li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>AntiX semble ne plus avoir de forum de communauté actif</li>
<li>Devuan a son propre forum, en langue anglaise : <a href="https://dev1galaxy.org/" rel="external">https://dev1galaxy.org/</a></li>
<li>Siduction a son propre forum, en langue anglaise : <a href="https://forum.siduction.org/" rel="external">https://forum.siduction.org/</a></li>
<li>Xebian a une communauté d&rsquo;utilisateurs accessible seulement sur IRC, en anglais.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Pour les débutants, concernant la version stable de Debian :
<ul>
<li><a href="https://debian-facile.org/projets/lescahiersdudebutant/" rel="external">https://debian-facile.org/projets/lescahiersdudebutant/</a></li>
</ul>
</li>
<li>Pour les chevronnés : <a href="https://debian-handbook.info/browse/fr-FR/stable/" rel="external">https://debian-handbook.info/browse/fr-FR/stable/</a>
<em>(documentation obsolète basée sur la Debian stable 11)</em>.</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Apprendre à gérer une Debian Unstable, appelée Sid - de même, pour la Devuan Ceres]]></summary>
        <published>2020-06-18T16:42:43+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f00f535a-00df-a464-02df-37e2299e951e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/checkrestart/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Checkrestart : retrouver les programmes à redémarrer / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="checkrestart" scheme="http://doc.huc.fr.eu.org/fr/tags/checkrestart/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>checkrestart</strong> est un programme conçu pour aider à trouver les
processus qui ont besoin d&rsquo;être redémarrés après une mise à jour.</p>
<p>checkrestart parcourt entièrement la table de fichiers du système, à la
recherche de processus ayant des nœuds détachés du système de fichiers.</p>
<hr>
<ul>
<li>Architectures gérées : aarch64 alpha amd64 arm hppa i386 mips64 mips64el
powerpc sparc64</li>
<li>Mainteneur : Sebastien Marie <a href="mailto:semarie@online.fr" rel="external">semarie@online.fr</a></li>
<li>Openports : <a href="https://openports.pl/path/sysutils/checkrestart" rel="external">https://openports.pl/path/sysutils/checkrestart</a></li>
<li>WWW: <a href="https://github.com/semarie/checkrestart" rel="external">https://github.com/semarie/checkrestart</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>checkrestart</code></strong>.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Très simplement : <code># checkrestart</code></p>
<h3 id="exemple">Exemple</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# checkrestart
</span></span><span style="display:flex;"><span><span style="color:#f99b15">76195</span>   pflogd
</span></span><span style="display:flex;"><span><span style="color:#f99b15">47538</span>   pflogd
</span></span><span style="display:flex;"><span><span style="color:#f99b15">54214</span>   slaacd
</span></span><span style="display:flex;"><span><span style="color:#f99b15">50500</span>   slaacd
</span></span><span style="display:flex;"><span><span style="color:#f99b15">41162</span>   slaacd
</span></span></code></pre></div><p>Il faut donc <a class="inside" href="/fr/sys/openbsd/rcctl/#red%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">redémarrer les services</a>

en question, qui dans cet exemple sont <code>pflogd</code> et <code>slaacd</code>.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/checkrestart/#man-8-checkrestart">man 8 checkrestart</a></li>
</ul>
<h3 id="man-8-checkrestart">man 8 checkrestart</h3>
<p><strong>checkrestart</strong> - une aide pour trouver les programmes qui ont besoin
d&rsquo;être redémarrés.</p>
<h4 id="synopsis">Synopsis</h4>
<p><strong>checkrestart</strong> [<strong>-v</strong>] [<strong>-M</strong> core] [<strong>-N</strong> system] [<strong>-W</strong> swap]</p>
<h4 id="description-1">Description</h4>
<p><strong>checkrestart</strong> est un programme conçu pour aider à trouver les
processus qui ont besoin d&rsquo;être redémarrés après une mise à jour.</p>
<p><strong>checkrestart</strong> parcourt entièrement la table des fichiers sur le
système à la recherche de nœuds de processus VTEXT détachés du système
de fichiers.</p>
<p>Par défaut, <strong>checkrestart</strong> affichera l&rsquo;identifiant du processus et le
nom de l&rsquo;exécutable du processus en cours.</p>
<p>Les options sont les suivantes :</p>
<ul>
<li><strong>-v</strong> : mode verbeux. <strong>checkrestart</strong> affichera en plus l&rsquo;inode et
le point de montage du nœud non lié.</li>
<li><strong>-M</strong> core : extrait des valeurs associées à une liste de noms selon
le cœur spécifié au lieu du noyau.</li>
<li><strong>-N</strong> system : extrait la liste de noms depuis le système spécifié au
lieu du noyau.</li>
<li><strong>-W</strong> swap : extrait l&rsquo;information swap depuis le fichier spécifié au
lieu du noyau.</li>
</ul>
<p>Cas d&rsquo;utilisation typique :</p>
<ul>
<li>démarrez un programme fonctionnant longtemps</li>
<li>plus tard, mettez à jour vos paquets via <code>pkg_add -u</code></li>
<li>si un programme est mis à jour, le programme correspondant en
fonctionnement est toujours l&rsquo;ancienne version (sans les correctifs
de sécurité, par exemple)</li>
<li>checkrestart vous dira quels processus sont derrière ce programme.</li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="https://man.openbsd.org/fstat" rel="external">fstat(1)</a>.</li>
</ul>
<h4 id="histoire">Histoire</h4>
<p>Le nom <strong>checkrestart</strong> vient d&rsquo;un
<a href="https://manpages.debian.org/buster/debian-goodies/checkrestart.1.en.html" rel="external">outil similaire sur Debian</a>
qui est relié à <a href="https://manpages.debian.org/buster/lsof/lsof.8.en.html" rel="external">lsof(1)</a>
<em><a href="http://www.linuxcertif.com/man/8/lsof/" rel="external">FR</a></em> pour aboutir au même
résultat.</p>
<h4 id="auteurs">Auteurs</h4>
<p><strong>checkrestart</strong> a été écrit par Sebastien Marie <a href="mailto:semarie@online.fr" rel="external">semarie@online.fr</a>.</p>
<h4 id="avertissements">Avertissements</h4>
<p>Seuls les nœuds VTEXT sont rapportés par <strong>checkrestart</strong>. Certains
programmes qui utilisent d&rsquo;anciennes bibliothèques ne sont pas rapportés
du fait d&rsquo;un manque de support dans le noyau.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[checkrestart : une aide pour trouver les programmes qui ont besoin d&#39;être redémarrés sous OpenBSD]]></summary>
        <published>2020-06-18T10:33:38+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:7e7b3fd5-2c18-e9cd-4db5-9cd892cb5d30</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-ffs2/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: FFS2 : Système de Fichiers v2 sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="FFS" scheme="http://doc.huc.fr.eu.org/fr/tags/ffs/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Depuis OpenBSD 6.7, le système de fichiers FFS2 - pour <em>Enhanced Fast Filesystem</em> -
est disponible, dans les contextes suivants :</p>
<ul>
<li>par défaut, lors d&rsquo;une installation neuve d&rsquo;OpenBSD 6.7 ou supérieure
<ul>
<li><em>ce qui inclut la -current suivant la 6.7, quelque soit la taille
de la partition</em>.</li>
</ul>
</li>
<li>par défaut, lors d&rsquo;une création d&rsquo;une nouvelle partition d&rsquo;une taille
supérieure à 1 To - <em>depuis OpenBSD 4.2</em>.</li>
<li>ou lors d&rsquo;une création manuelle d&rsquo;une nouvelle partition en utilisant
<a href="https://man.openbsd.org/newfs.8" rel="external"><code>newfs</code>(8)</a> avec l&rsquo;option <code>-O2</code>,
pour les tailles plus petites.</li>
</ul>
<p>Toutes les <a href="https://www.openbsd.org/plat.html" rel="external">architectures supportées</a>
par le projet OpenBSD en bénéficient.</p>
<h2 id="bénéfices">Bénéfices</h2>
<ul>
<li>FFS2 est plus rapide que sa version précédente FFS pour créer le
système de fichier, mais aussi pour l&rsquo;analyser avec l&rsquo;outil
<a href="https://man.openbsd.org/fsck.8" rel="external"><code>fsck</code>(8)</a>.</li>
<li>FFS2 utilise une horloge de datation sur 64 bits
<ul>
<li><em>il n&rsquo;est donc pas soumis au <a href="https://fr.wikipedia.org/wiki/Bug_de_l%27an_2038" rel="external">bogue de l&rsquo;an 2038</a></em>.</li>
</ul>
</li>
<li>FFS2 supporte des partitions beaucoup plus grandes
<ul>
<li><em>attention, les super grandes partitions ne sont pas recommandées,
car elles demandent, par exemple, plus de mémoire lors d&rsquo;analyse avec
<code>fsck()</code> surtout si de nombreux inodes sont utilisés</em>.</li>
</ul>
</li>
</ul>
<h2 id="convertir-ffs--ffs2">Convertir FFS ⇒ FFS2</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">AVANT toute manipulation de ce type, il est <strong>hautement recommandé de
faire une sauvegarde de toutes vos données</strong> ; vous êtes averti !</div>

<p>Le plus simple pour convertir une partition est de faire une nouvelle
installation avec une image de la version 6.7 ou supérieure.</p>
<p>Néanmoins, il est possible de le faire en quelques petites étapes simples :</p>
<ul>
<li>il est recommandé d&rsquo;être en mode utilisateur unique <em>(single user mode)</em></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># umount</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># dump</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># newfs -O2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># restore</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mount</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Attention, les commandes présentées ci-dessus ne sont pas complètes,
dans le sens où elle ne précise pas le disque ou la partition à cibler ;
il est important de lire les manpages correspondants pour les utiliser
correctement.</p>
<ul>
<li>dump(8) : <a href="https://man.openbsd.org/dump.8" rel="external">https://man.openbsd.org/dump.8</a></li>
<li>newfs(8) :  <a href="https://man.openbsd.org/newfs.8" rel="external">https://man.openbsd.org/newfs.8</a></li>
<li>restore(8) : <a href="https://man.openbsd.org/restore.8" rel="external">https://man.openbsd.org/restore.8</a></li>
</ul></div>

<p>Pour finir, redémarrez la machine…</p>
<p>Et, voilà !</p>
<hr>
<h2 id="histoire">Histoire</h2>
<ul>
<li>FFS2 est apparu la première fois dans
<a href="https://www.openbsd.org/42.html" rel="external">OpenBSD 4.2</a> - <a href="https://www.openbsd.org/plus42.html" rel="external">Changelog 4.2</a></li>
<li>Ajout du support de FFS, le 13 Avril 2007 - cf:
<a href="https://cvsweb.openbsd.org/src/sbin/newfs/newfs.c?rev=1.57&amp;content-type=text/x-cvsweb-markup" rel="external">CVSWeb newfs n°1.57</a></li>
<li>FFS2 devient le FS par défaut pour les grands systèmes de fichiers,
ayant un bloc d&rsquo;entier supérieur à 512 octets - cf:
<a href="https://cvsweb.openbsd.org/src/sbin/newfs/newfs.c?rev=1.82&amp;content-type=text/x-cvsweb-markup" rel="external">CVSWeb newfs n°1.82</a></li>
</ul>
<hr>
<p><em>cf : <a href="https://marc.info/?l=openbsd-misc&amp;m=159061305709736&amp;w=2" rel="external">source</a></em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comprendre le système de fichiers FFS2 d&#39;OpenBSD]]></summary>
        <published>2020-05-30T18:48:27+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b569679a-cfa8-ed48-e110-49d33db9c9b9</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/httpd/httpd-delivre-fichiers-compresses/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: httpd : délivrer des fichiers statiques compressés (&#43; slowcgi)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="slowcgi" scheme="http://doc.huc.fr.eu.org/fr/tags/slowcgi/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="CGI" scheme="http://doc.huc.fr.eu.org/fr/tags/cgi/" />
        <category term="deflate" scheme="http://doc.huc.fr.eu.org/fr/tags/deflate/" />
        <category term="gzip" scheme="http://doc.huc.fr.eu.org/fr/tags/gzip/" />
        <category term="brotli" scheme="http://doc.huc.fr.eu.org/fr/tags/brotli/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base :</p>
<ul>
<li>
<p>un serveur web, nommé <strong>httpd</strong>, depuis 5.7 - <em>que j&rsquo;ai présenté plus
ou moins succinctement 
<a class="inside" href="/fr/web/httpd/httpd/" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">ici</a>
</em></p>
</li>
<li>
<p>un serveur CGI, nommé <strong>slowcgi</strong>, depuis 5.4</p>
</li>
<li>
<p>Site web : <a href="https://bsd.plumbing/" rel="external">https://bsd.plumbing/</a></p>
</li>
<li>
<p>OpenBSD : <strong>6.6, 6.7</strong></p>
</li>
</ul>
<hr>
<p><strong>Principe</strong> : si le client web informe qu&rsquo;il accepte l&rsquo;encodage de compression
aux formats deflate, gzip, br, alors <strong>httpd</strong> passe la main à <strong>slowcgi</strong>
qui délivre le contenu compressé correspondant.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il ne s&rsquo;agit en aucun cas de la compression à la volée !</div>

<p>Le problème est que le serveur <strong>httpd</strong> n&rsquo;est pas capable de gérer la
délivrance de contenu statique compressé.</p>
<p>L&rsquo;astuce est d&rsquo;utiliser le serveur CGI <strong>slowcgi</strong>, intégré lui-aussi dans
le système de base, pour assumer la délivrance de ce contenu statique compressé.</p>
<p>En effet, par le biais de script CGI - <em>ici, en shell</em> - nous allons pouvoir
assumer la délivrance de ces contenus statiques suivants :</p>
<ul>
<li>Formats de fichiers gérés : <strong>atom</strong>, <strong>css</strong>, <strong>html</strong>, <strong>js</strong>, <strong>json</strong>,
<strong>svg</strong>, <strong>txt</strong>, <strong>xml</strong></li>
<li>aux deux formats de compression : que sont <strong>gzip</strong>, et <strong>brotli</strong>.</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Il est nécessaire de <a href="https://framagit.org/hucste/tools/-/raw/master/OpenBSD/slowcgi/sbw.cgi" rel="external">télécharger mon script <strong>sbw.cgi</strong></a>.</p>
<p>Une fois téléchargé, à vous de le mettre dans le répertoire <code>cgi-bin</code> du
chroot web. Le mieux étant d&rsquo;utiliser la commande <code>install</code> suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>install -o www -g bin -m <span style="color:#f99b15">0550</span> sbw.cgi /var/www/cgi-bin/sbw.cgi
</span></span></code></pre></div><p>qui nous permet de l&rsquo;installer proprement avec les droits minimum, strictement
nécessaire, attribué à l&rsquo;utilisateur web <code>www</code>, au groupe <code>bin</code>.</p>
<h3 id="dépendances">Dépendances</h3>
<p>Le script nécessite l&rsquo;installation de plusieurs binaires et quelques bibliothèques
à l&rsquo;intérieur du chroot web pour fonctionner correctement.</p>
<p>Il faut donc veiller à copier :</p>
<ul>
<li>
<p>le shell en premier, ainsi que les binaires <strong>cat</strong>, <strong>date</strong> et <strong>sha256</strong>,
qui se trouvent tous dans le répertoire système <code>/bin</code>.</p>
</li>
<li>
<p>les binaires <strong>basename</strong>, <strong>logger</strong> <sup><span class="orange">1</span>
</sup>,
<strong>stat</strong>, qui se trouvent être  dans le répertoire système <code>/usr/bin</code></p>
</li>
<li>
<p>la bibliothèque C partagée <code>/usr/lib/libc.so.xx.0</code>
<sup><span class="orange">2</span>
</sup></p>
</li>
<li>
<p>la bibliothèque d&rsquo;exécution <code>/usr/libexec/ld.so</code></p>
</li>
</ul>
<p>vers leurs répertoires respectifs dans le chroot web <code>/var/www/</code>.</p>
<p>Si tous doivent être assujettis à l&rsquo;utilisateur <code>root</code> et groupe <code>bin</code> :</p>
<ul>
<li>
<p>chacun des binaires doit avoir des droits 0555, par exemple :</p>
<ul>
<li>pour <strong>sh</strong> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>install -o root -g bin -m <span style="color:#f99b15">0555</span> /bin/sh /var/www/bin/
</span></span></code></pre></div><ul>
<li>pour <strong>stat</strong>  :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>install -o root -g bin -m <span style="color:#f99b15">0555</span> /usr/bin/stat /var/www/usr/bin/
</span></span></code></pre></div></li>
<li>
<p>et chacune des bibliothèques, des droits 0444 :</p>
<ul>
<li>pour la <strong>libc</strong> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>install -o root -g bin -m <span style="color:#f99b15">0444</span> /usr/lib/libc.so.xx.0 /var/www/usr/lib/
</span></span></code></pre></div><ul>
<li>pour <strong>ld.so</strong> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>install -o root -g bin -m <span style="color:#f99b15">0444</span> /usr/libexec/ld.so /var/www/usr/libexec/
</span></span></code></pre></div></li>
</ul>
<p>Cela nécessite de créer avant les répertoires correspondant dans le chroot web !</p>
<p>Mais comme je suis quelqu&rsquo;un de très gentil, retrouvez mon
<a href="https://framagit.org/hucste/tools/-/blob/master/OpenBSD/chroot_deps" rel="external">script de gestion des dépendances</a>.</p>
<hr>
<p><sup><span class="orange">1</span>
</sup> De l&rsquo;intérêt du binaire <code>logger</code> :
bien sûr que normalement, idéalement, nous n&rsquo;avons pas besoin du logger, mais
il a pour propos de journaliser certaines actions, qui en cas d&rsquo;échec, sont
intéressantes à faire écrire dans les journaux <code>/var/log/{daemon,messages}</code>.</p>
<p>De même, si la variable <code>debug</code> est paramétrée sur <code>1</code>, dans la fonction
principale, alors le logger restituera les valeurs correspondantes aux
différentes variables, à fin d&rsquo;analyse : s&rsquo;assurer que telle variable reçoit
bien une valeur, dans tel contexte, et si oui, quelle valeur !</p>
<p><sup><span class="orange">2</span>
</sup> La bibliothèque C partagée, entre
chaque version d&rsquo;OpenBSD, change aussi de nom. Ainsi, pour OpenBSD :</p>
<ul>
<li>v6.7 : <code>libc.so.96.0</code></li>
<li>v6.6 : <code>libc.so.95.1</code></li>
</ul>
<p>Ce détail est important et peut difficilement être scripté. Donc, lors de
changement de version d&rsquo;OpenBSD, il faut bien veiller à modifier le script
pour lui définir le nouveau nom de la bibliothèque, sinon il ne fonctionnera
pas !</p>
<hr>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">L&rsquo;astuce pour savoir quelles sont les dépendances liées à un binaire est
d&rsquo;utiliser la commande <code>ldd</code> sur le binaire en question.</div>

<h2 id="configuration">Configuration</h2>
<h3 id="httpd">httpd</h3>
<p>Il est nécessaire d&rsquo;ajouter dans votre contexte <code>server</code>, les déclarations
<code>location</code> suivantes :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">location &#34;/*.atom&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.css&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.html&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.js&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.json&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.svg&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.txt&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
location &#34;/*.xml&#34; { include &#34;/etc/httpd.d/sbw.conf&#34; }
</code></pre><p>Quant au cas du fichier <code> &quot;/etc/httpd.d/sbw.conf</code>, il renferme le contenu des
déclarations <code>fastcgi</code> suivantes :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">root &#34;/cgi-bin/sbw.cgi&#34;
fastcgi param realroot &#34;/htdocs/domaine.tld/www&#34;
fastcgi param cachecontrol &#34;1814400&#34;
fastcgi param file404 &#34;/404.html&#34;
</code></pre><p><strong>Explications</strong> :</p>
<p>Il importe de définir au moins :</p>
<ul>
<li><strong>root</strong> pour lui signifier le chemin relatif au chroot web, du script
CGI à exécuter.</li>
<li>le paramètre <strong>realroot</strong> : bien indiquer la racine vers votre espace
web, au sein du chroot web.</li>
<li>les autres paramètres sont certes optionnels mais néanmoins utiles à
envoyer au script CGI, surtout celui de la gestion du cache.</li>
</ul>
<h3 id="slowcgi">slowcgi</h3>
<p>Le serveur <strong>slowgci</strong> ne nécessite aucune configuration. Il nécessite
seulement d&rsquo;être activé et démarré avec l&rsquo;outil de contrôle <code>rcctl</code>.</p>
<h2 id="histoire">Histoire</h2>
<h3 id="des-failles">Des failles</h3>
<p>En effet, l&rsquo;histoire du protocole <abbr title="HyperText Transfert Protocol">HTTP</abbr>
 nous
a révélé deux failles majeures liées à la compression à la volée, ou compression
dynamique de contenu : <strong>CRIME</strong> et <strong>BREACH</strong> - qui est dérivée de la première. <br>
Ces deux failles peuvent même impacter <abbr title="Transport Layer Secure">TLS</abbr>
.</p>
<p>Même si la plupart des clients web ont été corrigés pour s&rsquo;efforcer d&rsquo;atténuer
ces failles, il n&rsquo;est clairement pas recommandé d&rsquo;utiliser la méthode de
compression à la volée, que savent très bien gérer la plupart des serveurs HTTP.</p>
<p>Parmi les parades, a été l&rsquo;adoption depuis HTTP 1.1 du transfert par encodage
de bloc - <em>la fameuse entête <code>Transfer-Encoding: chunked</code></em> - de même, il est
fortement recommandé de mettre en place une politique <strong>Referrer</strong> afin de
n&rsquo;autoriser que la délivrance de contenu compressé QUE depuis le domaine
en cours, et de la refuser depuis tout autre domaine duquel du contenu est
appelé (CSS, JS, fonts, json, etc.).</p>
<h3 id="relative-à-httpd">Relative à httpd</h3>
<p>L&rsquo;auteur Reyk Floeter se <a href="https://github.com/reyk/httpd/issues/21" rel="external">refuse à la prise en charge de contenu compressé</a>.
Et, même si une <a href="https://github.com/reyk/httpd/issues/80" rel="external">requête</a> a été faite pour délivrer du contenu déjà compressé,
ce n&rsquo;est pas prêt d&rsquo;être intégré.</p>
<h3 id="brotli">brotli</h3>
<p>Le format <strong>brotli</strong> est un format de compression inventé par une équipe
de l&rsquo;entreprise Google. Il est considéré comme étant le successeur de gzip
car plus rapide et un meilleur taux de compression.</p>
<p>En savoir plus :</p>
<ul>
<li><a href="https://brotli.org/" rel="external">https://brotli.org/</a></li>
<li>Est-ce que votre client web le supporte : <a href="https://caniuse.com/#search=brotli" rel="external">https://caniuse.com/#search=brotli</a></li>
</ul>
<p>À savoir que <strong>curl</strong> gére le format brotli, depuis la sortie de sa version
7.57.0, par l&rsquo;usage de l&rsquo;option <code>--compressed</code>, voire de l&rsquo;option <code>-H</code>  -
<em>option qui permet de gérer finement les entêtes HTTP</em>. <em>(cf : lire son <a href="https://curl.haxx.se/docs/manpage.html" rel="external">manpage</a>)</em></p>
<h4 id="clients-non-supportés">clients non supportés</h4>
<ul>
<li>L&rsquo;outil <strong>curl</strong> sous OpenBSD semble ne pas supporter le format de compression,
bien que celui-ci soit intégré dans le code de source de l&rsquo;outil.</li>
<li>De même, les clients web console que sont <strong>lynx</strong>, et <strong>w3m</strong> ne prennent
pas en charge brotli, quelque soit l&rsquo;OS.</li>
</ul>
<h3 id="firefox">Firefox</h3>
<p>Ahhh, fichu Firefox, qui depuis la version 64, <a href="https://support.mozilla.org/fr/kb/remplacer-lecteur-de-flux-firefox" rel="external">ne gére plus nativement les flux</a>
de syndication Atom et RSS.</p>
<p>En fait, c&rsquo;est plus subtil qu&rsquo;il n&rsquo;y paraît. Si vous délivrez le contenu
Atom et RSS avec le mime type <strong>text/xml</strong>, puisqu&rsquo;après tout, tous les deux
sont bel et bien des fichiers XML, alors Firefox acceptera de les lire
nativement et de vous les afficher. Il ne les mettra pas en forme, mais
il vous affichera le contenu.</p>
<p>Si vous les délivrer avec leur propre type de contenu, à savoir respectivement
<strong>application/atom+xml</strong> et <strong>application/rss+xml</strong>, tous les deux normés par
une 















































































<span lang="en">RFC <em>(Requests for comments)</em></span>































 ou l&rsquo;autre, alors Firefox vous demandera quoi en faire !</p>
<p>Une aberration sans nom !!!</p>
<h3 id="la-petite-histoire">La petite histoire</h3>
<p>Pour la petit histoire, Xavier Cartron @prx est l&rsquo;auteur original de cette
idée de délivrer du contenu statique compressé.</p>
<p>Le travail que j&rsquo;ai effectué se base sur sa première version de script CGI
shell. Mais elle ne me satisfaisait pas, pour plusieurs raisons, car il
se contente à délivrer au format gzip, QUE SI gzip est demandé.</p>
<p>Il a eu l&rsquo;idée géniale d&rsquo;ajouter la gestion de l&rsquo;entête <code>ETag</code>, qui sert à
fixer un identifiant par ressource délivrée. C&rsquo;est dans ce contexte, que
le binaire <strong>sha256</strong> est utile.</p>
<hr>
<p>Ayant entendu parler du format de compression <a href="/fr/web/httpd/httpd-delivre-fichiers-compresses/#brotli">brotli</a>, j&rsquo;ai donc
repris/continué l&rsquo;écriture afin de pouvoir délivrer du contenu statique
compressé précédemment avec ce format.</p>
<p>Ensuite, j&rsquo;ai ajouté le code nécessaire pour la gestion des entêtes nécessaires :</p>
<ul>
<li>
<p><code>Content-Length</code> : pour envoyer le poids du document quelque soit sa version ;
<em>c&rsquo;est dans ce contexte que le binaire <strong>stat</strong> est nécessaire</em>.</p>
</li>
<li>
<p><code>Last-Modified</code> : pour récupèrer la date de modification du document à
délivrer ; d&rsquo;aucun considère que cette entête est plus pertinente que <strong>ETag</strong>. <br>
<em>C&rsquo;est dans ce contexte que les binaires <strong>date</strong> et <strong>stats</strong> sont utiles</em>.</p>
</li>
<li>
<p><code>Transfer-Encoding</code> : pour envoyer le document à délivrer dans le bon
format de compression, si besoin est.</p>
</li>
</ul>
<p>Puis, j&rsquo;ai écrit le code nécessaire pour détecter si les dépendances utiles
étaient bien dans le chroot web, autrement le script ne peut fonctionner.
Si les dépendances ne sont pas installées, alors le serveur renvoie une
erreur 500, avec un message HTML décryptant l&rsquo;erreur.</p>
<p><strong>Attention</strong> :  le script n&rsquo;installe pas et ne peut pas installer les
dépendances, du fait d&rsquo;être dans le chroot web, il ne peut voir ce qui se
passe au-delà !</p>
<p>Puis, après quelques recherches sur le web, j&rsquo;ai compris que le format de
compression <strong>deflate</strong> qui peut être demandé par certains clients web, est
compris dans le format de compression gzip, de là, la prise en charge.</p>
<hr>
<p>Mais j&rsquo;étais confronté à des dysfonctionnements que je n&rsquo;arrivais pas à
comprendre et encore moins à résoudre. Et, là deux &ldquo;choses&rdquo; m&rsquo;ont sérieusement
aider à avancer - <em>car, à moment donné, ne m&rsquo;en sentant plus les capacités,
j&rsquo;ai tout simplement laissé tomber, n&rsquo;y arrivant pas, ne trouvant pas l&rsquo;aide
nécessaire pour avancer</em> - :</p>
<ul>
<li>Solène Rapenne, de l&rsquo;équipe d&rsquo;OpenBSD, m&rsquo;a aidé à comprendre que je faisais
l&rsquo;erreur d&rsquo;envoyer en trop des retours à la ligne, alors qu&rsquo;il m&rsquo;en faut
un seul, au bon moment, celui entre l&rsquo;envoi des différentes entêtes
et l&rsquo;envoi du document lui-même, qu&rsquo;il soit compressé ou non.</li>
<li>l&rsquo;idée d&rsquo;implémenter une variable <code>debug</code> et d&rsquo;utiliser le binaire <code>logger</code>
pour m&rsquo;assurer des différents retours.</li>
</ul>
<p>Une astuce que m&rsquo;a donné Solène est l&rsquo;usage en local de cette commande :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>env <span style="color:#ef6155">HTTP_ACCEPT_ENCODING</span><span style="color:#5bc4bf">=</span>br <span style="color:#ef6155">realroot</span><span style="color:#5bc4bf">=</span>/var/www/htdocs/domaine.tld/dev/ <span style="color:#ef6155">PATH_INFO</span><span style="color:#5bc4bf">=</span>index.html /var/www/cgi-bin/sbw.cgi | less
</span></span></code></pre></div><p>m&rsquo;expliquant qu&rsquo;il est possible d&rsquo;interroger localement directement le script
CGI, en lui envoyant les différentes valeurs possibles lors de l&rsquo;appel…
via les variables d&rsquo;environnements.<br>
<strong>Idée géniale !</strong></p>
<hr>
<p>À ce propos, étant donné que nous avons installé le script shell CGI <strong>sbw.cgi</strong>
avec des droits utilisateurs <strong>0550</strong>, vous aurez le droit à cette petite
erreur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>env: /var/www/cgi-bin/sbw2.cgi: Permission denied
</span></span></code></pre></div><p>il suffit de changer le droit d&rsquo;exécution pour les autres ;-) <em>(<code>0551</code>, ou <code>+x</code>)</em></p>
<hr>
<p>J&rsquo;ai amélioré la détection du mime type en l&rsquo;obtenant à partir du fichier
appelé sur le système - <em>qui nécessite l&rsquo;usage du binaire <strong>basename</strong></em> -
et la gestion des types de contenu des flux de syndication Atom ou RSS.</p>
<p>Pour finir, j&rsquo;ai écrit le code nécessaire pour détecter si l&rsquo;agent utilisateur
était <a href="/fr/web/httpd/httpd-delivre-fichiers-compresses/#firefox">Firefox</a>.</p>
<ul>
<li>Si oui, pour récupèrer son numéro de version, <em>car étant donné que les flux
de syndication ne sont plus correctement supportés</em>, un petit pack était
nécessaire pour lui délivrer les flux Atom et RSS au format &ldquo;trompeur&rdquo;
<strong>text/xml</strong>. Ainsi, Firefox accepte de le lire au-lieu de demander à l&rsquo;ouvrir
avec une autre application.</li>
</ul>
<p>J&rsquo;ai écrit la première mouture de ce hack nécessitant l&rsquo;ajout des binaires
<code>grep</code> et  <code>awk</code> - <em>solution qui ne me satisfaisait pas, mais fonctionnelle</em>. <br>
Et, <del>suite à la <a href="https://forum.openbsd.fr.eu.org/showthread.php?tid=2620&amp;pid=20898#pid20898" rel="external">réflexion de l&rsquo;utilisateur @eol, sur le forum de la communauté
française d&rsquo;&ldquo;OpenBSD pour tous&rdquo;</a></del>, j&rsquo;ai remplacé par un travail sur l&rsquo;expansion
des variables en shell.</p>
<p>Et, voilà !</p>
<hr>
<p>Actuellement, @prx a réécrit son script shell en langage C :</p>
<ul>
<li>
<p>l&rsquo;avantage est qu&rsquo;il n&rsquo;y a besoin d&rsquo;aucune dépendance, et que c&rsquo;est &ldquo;protégé&rdquo;
par les mesures de sécurité sur les appels système que sont pledge(2)
et unveil(2).</p>
</li>
<li>
<p>néanmoins, il ne gère QUE la compression gzip ; de même certaines petites
choses ne sont pas gérées : pas de gestion de l&rsquo;entête <strong>Last-Modified</strong>,
ni du support brotli ou deflate, ou du moins pas directement|automatiquement.</p>
</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>En savoir plus sur la mise en place d&rsquo;une politique Referrer : 
<a class="inside" href="/fr/web/http/referrer/" title="Lien interne vers l&#39;article : 'HTTP : Referrer (header)'">HTTP : Referrer (header)</a>

</p>
<h3 id="manpage">manpage</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/install" title="Page du Manuel OpenBSD pour : install">install</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/slowcgi.8" title="Page du Manuel OpenBSD pour : slowcgi">slowcgi(8)</a>
, 
<a class="man" href="https://man.openbsd.org/rcctl.8" title="Page du Manuel OpenBSD pour : rcctl">rcctl(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/pledge.2" title="Page du Manuel OpenBSD pour : pledge">pledge(2)</a>
, 
<a class="man" href="https://man.openbsd.org/unveil.2" title="Page du Manuel OpenBSD pour : unveil">unveil(2)</a>
</li>
</ul>
<h3 id="wikipédia">Wikipédia</h3>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/BREACH" title="Article Wikipédia : BREACH">BREACH <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Délivrer du contenu compressé (au format deflate, gzip, brotli) de fichiers statiques (html, xml, css, js, json, …) par le biais du couple des serveurs natifs httpd&#43;slowcgi sous OpenBSD]]></summary>
        <published>2020-05-28T20:00:11+02:00</published>
        <updated>2025-11-18T16:07:44+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0985752e-3797-a298-6ad6-8a3b69c8cc62</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/megatools/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: megatools : logiciel CLI pour Mega sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="megatools" scheme="http://doc.huc.fr.eu.org/fr/tags/megatools/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Megatools</strong> est une collection de programmes pour accéder aux services
de Mega depuis la ligne de commande depuis votre machine ou serveur.</p>
<p>Megatools vous permet de copier des fichiers individuels voire une
arborescence de répertoires vers et depuis le nuage informatique. Vous
pouvez aussi permettre le téléchargement de flux, tels la prévisualisation
de vidéos et de fichiers audio, sans avoir le besoin de télécharger le
fichier en entier.</p>
<p>Megatools est robuste et optimisé pour les opérations rapides - autant
que les serveurs Mega le permettent. Les exigences de mémoire et
d&rsquo;utilisation de CPU sont réduites au minimum.</p>
<hr>
<ul>
<li>Architectures gérées : aarch64 alpha amd64 arm hppa i386 mips64 mips64el powerpc sparc64</li>
<li>Mainteneur : Anthony J. Bentley</li>
<li>Openports : <a href="https://openports.pl/path/net/megatools" rel="external">https://openports.pl/path/net/megatools</a></li>
<li>WWW: <a href="https://megatools.megous.com" rel="external">https://megatools.megous.com</a></li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>megatools</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>le fichier de configuration personnel est <code>~/.megarc</code>.</li>
</ul>
<p>Voici à quoi il ressemble, au minimum :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#815ba4">[Login]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Username</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">identifiant</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Password</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">mot-de-passe</span>
</span></span></code></pre></div><p><em>Pour rappel, merci de lire le <code>man megarc</code> pour connaître les
différentes options de configuration possibles.</em></p>
<h2 id="utilisation">Utilisation</h2>
<p>La première chose à tester, une fois votre <a href="/fr/sys/openbsd/megatools/#configuration">configuration</a>
faite, est la commande <code>megadf</code> qui permet de tester si la connexion se
fait bien avec le service, ainsi que l&rsquo;authentification avec ; tel que,
pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ megadf
</span></span><span style="display:flex;"><span>Total: <span style="color:#f99b15">53687091200</span>
</span></span><span style="display:flex;"><span>Used:  <span style="color:#f99b15">1163522967</span>
</span></span><span style="display:flex;"><span>Free:  <span style="color:#f99b15">52523568233</span>
</span></span></code></pre></div><p>Ainsi la commande retourne l&rsquo;espace total, celui utilisé et celui qui
est disponible.</p>
<hr>
<p>Cette <a href="https://megatools.megous.com/showcase.mp4" rel="external">vidéo</a> vous permet en
quelques minutes de comprendre l&rsquo;usage des différentes commandes. <br>
<strong>ATTENTION</strong> la commande <code>megasync</code>, mentionnée dans la vidéo, a été
remplacée par la commande <code>megacopy</code>**.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="error-you-must-specify-your-meganz-username-email">ERROR: You must specify your mega.nz username (email)</h3>
<p>Vous avez oublié de spécifier votre identifiant de connexion,
généralement votre courriel.</p>
<h3 id="error-cant-login-to-meganz">ERROR: Can&rsquo;t login to mega.nz</h3>
<p>Il est très probable que le mot de passe ou l&rsquo;identifiant que vous
fournissez ne soit pas le bon.</p>
<p>Résultat, vous ne pouvez pas vous connecter au service de Mega.</p>
<h3 id="you-need-to-provide-non-empty-password">You need to provide non-empty password!</h3>
<p>Vous n&rsquo;avez pas spécifié de mot de passe - donc pas de connexion au service.</p>
<h2 id="documentation">Documentation</h2>
<h3 id="manpages">manpages</h3>
<p>Une fois le paquet installé, sont accessibles les différents manpages sur votre OS :</p>
<ul>
<li><strong><a href="https://megatools.megous.com/man/megatools-copy.html" rel="external">megacopy(1)</a></strong> :  pour synchroniser un ou plusieurs fichiers</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-df.html" rel="external">megadf(1)</a></strong> : voir le quota et l&rsquo;utilisation de votre espace</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-dl.html" rel="external">megadl(1)</a></strong> : pour télécharger un fichier depuis un lien &ldquo;public&rdquo; Mega - ne nécessite pas d&rsquo;authentification</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-get.html" rel="external">megaget(1)</a></strong> : pour télécharger un fichier</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-ls.html" rel="external">megals(1)</a></strong> : lister les fichiers présents sur votre espace Mega</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-mkdir.html" rel="external">megamkdir(1)</a></strong> : créer un répertoire à distance sur votre espace Mega</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-put.html" rel="external">megaput(1)</a></strong> : téléverser un ou plusieurs fichiers sur votre espace Mega</li>
<li><strong><a href="https://megatools.megous.com/man/megarc.html" rel="external">megarc(5)</a></strong> : obtenir les informations utiles pour configurer son propre fichier de configuration.</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-reg.html" rel="external">megareg(1</a></strong> : pour créer et vérifier un compte</li>
<li><strong><a href="https://megatools.megous.com/man/megatools-rm.html" rel="external">megarm(1)</a></strong> : pour supprimer un ou plusieurs fichiers ou répertoires à distance de votre espace Mega.</li>
<li><strong><a href="https://megatools.megous.com/man/megatools.html" rel="external">megatools(7)</a></strong> :  le <strong>manpage principal</strong></li>
</ul>
<p>Ils sont ainsi accessibles sur Internet à l&rsquo;adresse suivante : <br>
<a href="https://megatools.megous.com/man/megatools.html" rel="external">https://megatools.megous.com/man/megatools.html</a></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[megatools est une collection d&#39;outils à utiliser sous OpenBSD pour les services du nuage informatique MEGA]]></summary>
        <published>2020-05-26T16:19:00+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:70fc2401-c178-a51c-a1af-4d8aa926e10f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tor-browser/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Tor Browser / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Tor" scheme="http://doc.huc.fr.eu.org/fr/tags/tor/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Tor Browser</strong> est une version personnalisée de
<a class="inside" href="/fr/sys/openbsd/firefox-esr/" title="Lien interne vers l&#39;article : 'Firefox ESR / OpenBSD'">Firefox-ESR</a>

spécifiquement préparée pour surfer sur Internet via le réseau anonyme Tor.</p>
<p>Sa configuration a pour but d&rsquo;atténuer les attaques contre
l&rsquo;anonymisation d&rsquo;un client, incluant le fait de déterminer son adresse
IP et l&rsquo;empreinte du navigateur. D&rsquo;autres aspects de Firefox ont aussi
été corrigés pour éviter autant que possible les failles de confidentialité.</p>
<p>Par défaut, sont inclus les modules <strong>NoScript</strong>, <strong>HTTPS Everywhere</strong>,
<strong>TorButton</strong>, et <strong>Tor-Launcher</strong>. Notez que du fait de l&rsquo;utilisation
du module NoScript, l&rsquo;utilisation de Javascript est bloqué par défaut.</p>
<p>Tor Browser utilise sa propre instance différente du port du serveur
<a class="inside" href="/fr/sys/openbsd/tor/" title="Lien interne vers l&#39;article : 'Tor : service d&#39;anonymat par onion routage / OpenBSD'">Tor</a>
, exécutée sur un autre port
que celui du serveur.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Note</strong> : Le port d&rsquo;OpenBSD n&rsquo;inclut pas encore le composant nommé
&ldquo;Pluggable Transports (PT)&rdquo;. De fait, toutes les fonctionnalités ne sont
pas encore disponibles, telle l&rsquo;utilisation par <code>obfsproxy</code>.</div>

<hr>
<ul>
<li>Architectures gérées : amd64 i386</li>
<li>Mainteneur : Caspar Schutijser</li>
<li>Openport : <a href="https://openports.pl/path/meta/tor-browser" rel="external">https://openports.pl/path/meta/tor-browser</a></li>
<li>WWW: <a href="https://www.torproject.org" rel="external">https://www.torproject.org</a></li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
meta-paquet <code>tor-browser</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Par défaut, <strong>Tor Browser</strong> enregistre sa configuration dans votre
répertoire personnel <code>~/TorBrowser-Data/</code>.</p>
<ul>
<li>
<p>Le sous-répertoire <code>Data</code> sert à enregistrer ses propres données :</p>
<ul>
<li><code>Data/Browser</code> : la configuration liée au client web</li>
<li><code>Data/tor_data</code> : lié au service daemon Tor</li>
<li><code>Data/torrc</code> : enregistre l&rsquo;instance Tor - par exemple, la
configuration des ponts (briges), …</li>
</ul>
</li>
</ul>
<h3 id="modules">Modules</h3>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>ATTENTION</strong> : ajouter des modules supplémentaires n&rsquo;est pas recommandé ;
le risque fort est de &ldquo;mettre en péril&rdquo; les mesures de protection liées
à <strong>Tor Browser</strong>, assurez-vous ABSOLUMENT d&rsquo;en avoir la stricte nécessité !</div>

<h4 id="keepassxc-browser">KeePassXC-Browser</h4>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce module de confidentialité semble ne pas fonctionner avec Tor Browser.</div>

<p>Depuis OpenBSD 6.6, le logiciel de confidentialité
<strong><a class="inside" href="/fr/sys/openbsd/keepassxc/" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC</a>
</strong> est installable.</p>
<p>Pour fonctionner correctement, il est nécessaire d&rsquo;installer le module
<strong>KeePassXC-Browser</strong>.</p>
<ul>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/keepassxc-browser/" rel="external">https://addons.mozilla.org/fr/firefox/addon/keepassxc-browser/</a></li>
</ul>
<p>Lire la page <strong>KeePassXC</strong> pour avoir plus d&rsquo;informations concernant le
module <a class="inside" href="/fr/sys/openbsd/keepassxc/#keepassxc-browser" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC-Browser</a>
</p>
<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de <strong>lire le fichier</strong>
<code>/usr/local/share/doc/pkg-readmes/tor-browser</code>.</p>
<hr>
<p>La documentation officielle - <em>en anglais</em> - :</p>
<ul>
<li><a href="https://2019.www.torproject.org/docs/documentation.html.en" rel="external">https://2019.www.torproject.org/docs/documentation.html.en</a></li>
<li>le manuel : <a href="https://tb-manual.torproject.org/fr/" rel="external">https://tb-manual.torproject.org/fr/</a></li>
<li>le wiki : <a href="https://trac.torproject.org/projects/tor/wiki" rel="external">https://trac.torproject.org/projects/tor/wiki</a></li>
<li>à-propos de PT : <a href="https://2019.www.torproject.org/docs/pluggable-transports.html.en" rel="external">https://2019.www.torproject.org/docs/pluggable-transports.html.en</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le navigateur web &#39;Tor Browser&#39; pour surfer anonymement sur le web, par le biais du réseau Tor, sous OpenBSD]]></summary>
        <published>2020-05-24T10:39:47+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:06e9dcf1-fda8-998a-1255-83e68af8e6d8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/keepassxc/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: KeepassXC : outil de gestion de données sensibles / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="KeepassXC" scheme="http://doc.huc.fr.eu.org/fr/tags/keepassxc/" />
        <category term="confidentialité" scheme="http://doc.huc.fr.eu.org/fr/tags/confidentialit%C3%A9/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://keepassxc.org" rel="external">KeePassXC</a></strong> est un dérivé communautaire de
KeePassX, le port multi-plateforme de KeePass pour Windows. Chaque
fonctionnalité travaille sur ces plateformes et fait l&rsquo;objet de tests
approfondis afin de fournir aux utilisateurs les mêmes apparences et
sensations sur chacun des systèmes d&rsquo;exploitation supportés. Cela inclut
la bien-aimée fonctionnalité <strong>Auto-Type</strong>.</p>
<p>Par défaut, la basse de données est toujours chiffrée avec l&rsquo;algorithme
de chiffrement AES (alias Rijndael) de norme industrielle, utilisant une
clé de 256 bits. KeePassXC utilise un format de basse de données
compatible avec KeePass Password Safe. Votre porte-monnaie fonctionne
hors-ligne et ne requiert pas de connexion Internet.</p>
<p>Les principales fonctionnalités :</p>
<ul>
<li>Un enregistrement des mots de passes et autres données confidentielles
avec les chiffrements AES, Twofish ou ChaCha20</li>
<li>Un format de fichier compatible avec KeePass2, KeePassX, MacPass,
KeeWeb et beaucoup d&rsquo;autres (KDBX 3.1 et 4.0)</li>
<li>Intégration de l&rsquo;agent SSH</li>
<li>Auto-Type sur toutes les plateformes supportés pour remplir
automatiquement les formulaires de connexions</li>
<li>La prise en charge de fichier Clé et du challenge de réponse
YubiKey pour une sécurité accrue.</li>
<li>La génération de TOTP (incluant Steam Guard)</li>
<li>L&rsquo;import CVS depuis d&rsquo;autres gestionnaires de mots de passse (tel que
LastPass)</li>
<li>Une interface en ligne de commande CLI</li>
<li>Un générateur de mots de passe ou de passphrase unique</li>
<li>Une mesure de la force du mot de passe</li>
<li>La fonctionnalité de fusion de base de données</li>
<li>Une recharge automatique lorsque la base de données a été changée</li>
</ul>
<p>WWW: <a href="https://keepassxc.org" rel="external">https://keepassxc.org</a></p>
<h2 id="installation">Installation</h2>
<p>Disponible depuis OpenBSD 6.6 !</p>
<p>Actuellement, il existe 4 versions que vous pouvez
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 :</p>
<ul>
<li><code>keepassxc</code> : la version de base</li>
<li><code>keepassxc-browser</code> : la version d&rsquo;intégration avec les navigateurs internet</li>
<li><code>keepassxc-browser-yubikey</code> : la version d&rsquo;intégration pour les navigateurs
et pour fonctionner avec les clés USB de sécurité de type Yubikey</li>
<li><code>keepassxc-yubikey</code> : la version fonctionnant avec les clés de type Yubikey</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">La fonction communiquant avec une clé Yubikey ne fonctionne qu&rsquo;à partir
d&rsquo;OpenBSD 6.7 !</div>

<h2 id="configuration">Configuration</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne pas confondre les <a href="/fr/sys/openbsd/keepassxc/#paramètres">paramètres de configuration</a> de l&rsquo;outil
KeePassXC et <a href="/fr/sys/openbsd/keepassxc/#paramètres-de-la-base-de-données">ceux de la base de données</a>.</div>

<h3 id="paramètres">Paramètres</h3>
<p>La gestion des paramètres, une fois KeePassXC ouvert, se fait par le
biais du menu <strong><u>O</u>utils &gt; <u>P</u>aramètres</strong>.</p>
<h4 id="intégrations-aux-navigateurs">Intégrations aux navigateurs</h4>
<p>Cliquez sur l&rsquo;icône <strong>Intégration aux navigateurs</strong>, puis dans la partie
droite de la fenêtre cliquez sur la case à cocher
<strong>[ ] Activer l&rsquo;intégration aux navigateurs</strong>.</p>
<p>Une fois activée, les onglets <strong>Général</strong> et <strong>Avancé</strong> sont accessibles.</p>
<p>⇒ L&rsquo;onglet <strong>Général</strong> précise qu&rsquo;il faut télécharger le module
<strong>KeePassXC-Browser</strong> correspondant au client web que vous utilisez.
Une fois téléchargé, il faut activer l&rsquo;intégration pour le(s) navigateur(s)
en question.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Sous OpenBSD, les trois navigateurs web :</p>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/firefox/" title="Lien interne vers l&#39;article : 'Firefox / OpenBSD'">Firefox</a>
,</li>
<li><a class="inside" href="/fr/sys/openbsd/chromium/" title="Lien interne vers l&#39;article : 'Chromium / OpenBSD'">Chromium</a>
,</li>
<li>et <a class="inside" href="/fr/sys/openbsd/tor-browser/" title="Lien interne vers l&#39;article : 'Tor Browser / OpenBSD'">Tor-Browser</a></li>
</ul>
<p>… sont disponibles.</p>
</div>

<p>⇒ L&rsquo;onglet &ldquo;Avancé&rdquo; permet, entres autres, la prise en charge correcte
de la communication entre KeePassXC et le navigateur web. Activez les
cases à cocher suivantes :</p>
<ul>
<li><strong>[ ] Utiliser une application proxy entre KeePassXC et l&rsquo;extension pour un navigateur web</strong></li>
<li><strong>[ ] Utiliser un proxy personnalisé</strong>, puis</li>
<li>dans le champ de rechercher [ Parcourir… ], choisissez <code>/usr/local/bin/keepassxc-proxy</code></li>
</ul>
<p><em>Dans les deux contextes, il existe d&rsquo;autres options que vous pouvez
activer ou non…</em></p>
<h4 id="agent-ssh">Agent SSH</h4>
<p>Cliquez sur l&rsquo;icône &ldquo;Agent SSH&rdquo;, puis dans la partie droite de la fenêtre,
cliquez sur la case à cocher <strong>[ ] Activer l&rsquo;agent SSH</strong> <em>(redémarrage nécessaire)</em>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Le redémarrage en question est celui de l&rsquo;application ; fermez-la pour
l&rsquo;ouvrir à nouveau.</div>

<h4 id="intégration-au-secret-service">Intégration au Secret Service</h4>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Le <strong>Service Secret de Freedesktop</strong> semble être le service de gestion
de confidentialité des données sensibles normé par un des standards de
Freedesktop. Dans les faits, il gére votre porte monnaie de session X,
et bien d&rsquo;autres éléments de sécurité, dont la communication avec ses
éléments.</div>

<p>Cliquez sur l&rsquo;icône <strong>`Intégration au Secret Service</strong>, puis dans la
partie droite de la fenêtre cliquez sur la case à cocher
<strong>[ ] Activer l&rsquo;intégration de KeePassXC à Freedsktop.org Secret Service</strong>.</p>
<p>Une fois activée, les onglets <strong>Général</strong> et <strong>Autorisation</strong> sont
accessibles.</p>
<p>⇒ L&rsquo;onglet <strong>Général</strong>, outre les options diverses, donne un aperçu des
bases de données KP visibles, sous le dénominateur
<strong>Groupes de la base de données visibles :</strong></p>
<p>Ce groupe contient trois colonnes :</p>
<ul>
<li><strong>File Name</strong> : Nom du fichier de base de données</li>
<li><strong>Group</strong> : le groupe dans lequel peut être attribué le fichier de base
de données en question</li>
<li><strong>Manage</strong> : pour gérer le fichier de base de données :
<ul>
<li>Une icône bleue en forme de fichier pour éditer la base de données
<ul>
<li>lorsqu&rsquo;elle est cliquée, l&rsquo;application va dans le menu d&rsquo;édition
des <a href="/fr/sys/openbsd/keepassxc/#paramètres-de-la-base-de-données">paramètres de la base de données</a>.</li>
</ul>
</li>
<li>une icône en forme de cadenas ouvert - afin de verrouiller ou non
la base de donnée.</li>
</ul>
</li>
</ul>
<p>⇒ L&rsquo;onglet *<em>Autorisation</em> donne un aperçu des applications qui sont
autorisées de communiquer avec la base de données.</p>
<p>Deux colonnes :</p>
<ul>
<li><strong>Application</strong> : le nom des applications</li>
<li><strong>Manage</strong> : permet de gérer les autorisations liées à l&rsquo;application</li>
</ul>
<h3 id="paramètres-de-la-base-de-données">Paramètres de la base de données</h3>
<p>Les paramètres de la base de données sont accessibles par le menu
<strong><u>B</u>ase de données &gt; Paramètres de la base de <u>d</u>onnées…</strong></p>
<h4 id="sécurité">Sécurité</h4>
<p>Deux onglets sont accessibles :</p>
<ul>
<li><strong>Clé maître</strong></li>
<li><strong>Paramètres de chiffrement</strong></li>
</ul>
<p>⇒ L&rsquo;onglet <strong>Clé maître</strong> permet de gérer le mot de passe lié à la base
de données en cours.</p>
<p>Un bouton <strong>[ Ajouter une protection supplémentaire… ]</strong>, qui lorsqu&rsquo;il
est cliqué, donnera accès à la gestion :</p>
<ul>
<li>de protection par &ldquo;Fichier-clé&rdquo;</li>
<li>de challenge par question-réponse Yubikey.</li>
</ul>
<p>⇒ L&rsquo;onglet <strong>Paramètres de chiffrement</strong> permet le paramétrage d&rsquo;un
temps de déchiffrement de la base de données avant son possible accès,
ainsi que de choisir le format de celle-ci.</p>
<h4 id="intégration-au-secret-service-1">Intégration au Secret Service</h4>
<p>Le menu <strong>Entrées visibles</strong> permet de rendre visible ou non les données
qui sont dans la base de données.</p>
<h4 id="intégration-aux-navigateurs">Intégration aux navigateurs</h4>
<p>Ce menu permet de gérer les &ldquo;Paramètres de KeePassXC-Browser&rdquo; sur la
base de données, ainsi que les &ldquo;Clés stockées&rdquo;, relatives à la
communication entre KeePassXC et votre client web, par le biais du module
KeePassXC-Browser.</p>
<h4 id="paramètres-avancés">Paramètres avancés</h4>
<p>En bas, à gauche, de la fenêtre de KeePassXC, dans les paramètres de la
base de données se trouve une case à cocher <strong>[ ] Paramètres avancés</strong>.</p>
<p>La cocher modifie l&rsquo;apparence du menu <strong><a href="/fr/sys/openbsd/keepassxc/#sécurité">Sécurité</a></strong>
des paramètres de la base de données, et tout particulièrement dans
l&rsquo;onglet <strong>Paramètres de chiffrement</strong> qui permet ainsi de modifier plus
finement certaines options, tel l&rsquo;algorithme de chiffrement, la
fonction de dérivation, le cycle de transformation, l&rsquo;utilisation mémoire,
et le nombre de processus.</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>Ne touchez à ces paramètres que si vous comprenez, en connaissance de
cause, les implications de tels changements</strong>.</div>

<h2 id="utilisation">Utilisation</h2>
<h3 id="générateur-de-mot-de-passe">Générateur de mot de passe</h3>
<p>Le générateur de mot de passe ou de passphrase est accessible par le menu
<strong><u>O</u>utils &gt; Générateur de mot de <u>p</u>asse</strong>.</p>
<hr>
<h2 id="keepassxc-browser">KeePassXC-Browser</h2>
<p>Une fois ce module installé, et KeePassXC configuré pour communiquer avec
navigateur web, cliquez sur l&rsquo;icône du module pour gérer la communication
avec KeePassXC. Celui-ci vous demandera la première fois de créer une
clé de communication qui sera enregistrée dans les paramètres de la base
de données de KeePassXC.</p>
<ul>
<li>Le bouton vert <span class="kpxc-green">[ Paramètres ]</span> permet de
gérer les paramètres du module</li>
<li>Le bouton jaune <span class="kpxc-yellow">[ Choisir des champs d&rsquo;identification personnalisés pour cette page ]</span>
permet de paramétrer les champs de connexion sur une page web</li>
<li>alternativement un bouton bleu :
<ul>
<li><span class="kpxc-blue">[ Connecter ]</span> : quand il n&rsquo;y a jamais
eu d&rsquo;association de touche, afin de la créer.</li>
<li><span class="kpxc-blue">[ Recharger ]</span> permet de recharger la
clé de communication entre KeePassXC et le module KeePassXC-Browser
<ul>
<li>ce qui nécessite que KeePassXC soit en fonctionnement.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="mises-en-garde">Mises en garde</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il semble y avoir un souci empêchant le bon fonctionnement de communication
entre le module KeePassXC-Browser et KeePassXC si votre session utilise
<code>ck-launch</code>.</p>
<p>Modifiez votre fichier personnel <code>.xsession</code> pour redémarrer votre session
sans !</p>
</div>

<h3 id="messages-derreurs">Messages d&rsquo;erreurs</h3>
<ul>
<li>
<p><strong>KeePassXC-Browser n&rsquo;est pas configuré. Appuyez sur le bouton Connecter pour se connecter à KeePassXC.</strong> :
ce message est affiché lors du premier usage du module. Cliquez sur
le bouton [ Connecter ] pour créer une association de touches.</p>
</li>
<li>
<p><span class="kpxc-red">Échec du chiffrement du message. KeePassXC est-il lancé ?</span> :
Vérifiez que le logiciel KeePassXC soit activé !</p>
</li>
<li>
<p><span class="kpxc-red">Impossible de se connecter à KeePassXC. Vérifiez que
l’intégration au navigateur soit activée dans les paramètres de KeePassXC.</span>
signifie que <strong>le module KeePassXC-Browser ne peut se connecter à la
base de données KeePassXC</strong>.</p>
<ul>
<li>Soit vous n&rsquo;avez pas <a href="/fr/sys/openbsd/keepassxc/#integrations-aux-navigateurs">paramétré correctement KeePassXC</a>
pour qu&rsquo;ils puissent communiquer ensemble,</li>
<li>soit KeePassXC est tout simplement inactif.</li>
</ul>
</li>
<li>
<p><span class="kpxc-red">L’échange de clé a échoué.</span> : l&rsquo;échange
de la clé de communication entre le module KeePassXC-Browser et
KeePassXC n&rsquo;arrive pas à se faire.</p>
</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer des données privées et confidentielles, sous OpenBSD, grâce à l&#39;outil KeepassXC.]]></summary>
        <published>2020-05-23T15:02:22+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2c1646d3-0969-b4c1-8790-45aa8c72a286</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/httpd/relayd-log/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Relayd : Journalisation (Log)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="relayd" scheme="http://doc.huc.fr.eu.org/fr/tags/relayd/" />
        <category term="log" scheme="http://doc.huc.fr.eu.org/fr/tags/log/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base, depuis 5.7, le
serveur de relais nommé <strong>relayd</strong>.</p>
<ul>
<li>
<p>Site web : <a href="https://bsd.plumbing/" rel="external">https://bsd.plumbing/</a></p>
</li>
<li>
<p>OpenBSD : <strong>6.6, 6.7</strong></p>
</li>
</ul>
<hr>
<p>Le but de cet article est de savoir comment mettre en place une journalisation
du flux HTTP(S) qui passe au-travers de <strong>relayd</strong>.</p>
<p>C&rsquo;est très simple !</p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Par défault, le fichier de configuration : <code>/etc/relayd.conf</code></li>
</ul>
<h3 id="configuration-globale">Configuration Globale</h3>
<p>Dans un premier temps, nous devons déclarer le paramètre global <code>log</code>  dans
le fichier de configuration de <strong>relayd</strong>. <em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#log" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#log</a>
</em></p>
<p>Les déclarations de journal suivantes ont pour signification les suivantes :</p>
<ul>
<li><code>log state changes</code> ou <code>log host checks</code> sont utiles pour suivre l&rsquo;état
de l&rsquo;hôte ou les contrôles effectués dessus.
<ul>
<li>les états peuvent être de type :
<ul>
<li><code>up</code> si l&rsquo;état de santé de l&rsquo;hôte est positif</li>
<li><code>down</code> si celui est arrété ou si les contrôles ne sont pas bons.</li>
<li>en état <code>unknown</code> si l&rsquo;hôte est désactivé ou n&rsquo;a pas encore été
contrôlé.</li>
</ul>
</li>
</ul>
</li>
<li><code>log connection</code> nous permet de journaliser les connexions TCP, <strong>si relayd
est configuré en tant que relai(s)</strong> <sup><span class="orange">1</span>
</sup>.
À noter l&rsquo;ajout de l&rsquo;option <code>errors</code> pour le cas où nous voulons journaliser
que les erreurs de connexions TCP.</li>
</ul>
<p><sup><span class="orange">1</span>
</sup> <em>En effet, <strong>relayd</strong> peut aussi
être configuré en tant que routeur ou serveur de redirection</em>.</p>
<h3 id="règles-de-filtrage">Règles de filtrage</h3>
<p>Toujours dans le contexte du fichier de configuration de <strong>relayd</strong>, les
relais ont la possibilité de filtrer les connexions par le biais de paramètres
de filtrage spécifiques.</p>
<p>Ainsi nous utiliserons l&rsquo;action de correspondance <code>match</code> sur laquelle
nous appliquons l&rsquo;option de journalisation <code>log</code>. <em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#match" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#match</a>
</em> <br>
Cette action de correspondance s&rsquo;appliquera sur un type d&rsquo;action ;
actuellement, 5 types d&rsquo;actions sont définies :</p>
<ul>
<li><code>cookie</code> : une action qui a lieu sur un cookie. <sup><span class="orange">2</span>
</sup>
<em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#cookie" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#cookie</a>
</em></li>
<li><code>header</code> : une action ciblant le protocol d&rsquo;entête HTTP - les fameuses <strong>header</strong>s
<em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#header" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#header</a>
</em></li>
<li><code>path</code> : une action qui analyse le chemin de l&rsquo;URL demandée.
<sup><span class="orange">2</span>
</sup> <em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#path" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#path</a>
</em></li>
<li><code>query</code> : une action pour chercher la partie query de l&rsquo;URL demandée.
<sup><span class="orange">2</span>
</sup> <em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#query" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#query</a>
</em></li>
<li><code>url</code> : l&rsquo;action récupérant l&rsquo;URL complète… <sup><span class="orange">2</span>
</sup>
<em>
<a class="" href="https://man.openbsd.org/relayd.conf.5#url" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)#url</a>
</em></li>
</ul>
<p><sup><span class="orange">2</span>
</sup> <em>seulement disponible sur une requête HTTP.</em></p>
<h3 id="exemple-de-configuration">Exemple de configuration</h3>
<p>L&rsquo;exemple ci-dessous nous montre cinq règles de filtrage :</p>
<ul>
<li>les quatre premières ayant lieu sur une correspondance d&rsquo;entête</li>
<li>la dernière journalisant l&rsquo;URL dans son ensemble.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">### ips externe auth</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ip4</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;addresse-ipv4-public&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### manage logs</span>
</span></span><span style="display:flex;"><span>log state changes
</span></span><span style="display:flex;"><span>log connection
</span></span><span style="display:flex;"><span><span style="color:#776e71">#log connection errors</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>http protocol <span style="color:#48b685">&#34;hw&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    match header log <span style="color:#48b685">&#34;Host&#34;</span>
</span></span><span style="display:flex;"><span>    match header log <span style="color:#48b685">&#34;X-Forwarded-For&#34;</span>
</span></span><span style="display:flex;"><span>    match header log <span style="color:#48b685">&#34;User-Agent&#34;</span>
</span></span><span style="display:flex;"><span>    match header log <span style="color:#48b685">&#34;Referer&#34;</span>
</span></span><span style="display:flex;"><span>    match url log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    block
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>relay <span style="color:#48b685">&#34;www&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    listen on <span style="color:#ef6155">$ip4</span> port <span style="color:#f99b15">80</span>
</span></span><span style="display:flex;"><span>    protocol hw
</span></span><span style="display:flex;"><span>    forward to 127.0.0.1 port <span style="color:#f99b15">80</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><h2 id="journaux">Journaux</h2>
<p>Là encore, tout simplement, une fois la configuration établie, validée,
et le service relayd fonctionnel, les différents journaux se retrouvent
principalement dans :</p>
<ul>
<li><code>/var/log/daemon</code>,</li>
<li><code>/var/log/message</code>.</li>
</ul>
<h3 id="exemple-log-daemon">Exemple log daemon</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ grep relayd /var/log/daemon
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 16:37:21 sh1 relayd<span style="color:#5bc4bf">[</span>25237<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">13</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">2</span> active<span style="color:#5bc4bf">)</span>, 0, 192.168.1.1 -&gt; :80, <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 16:37:21 sh1 relayd<span style="color:#5bc4bf">[</span>45869<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">7</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">2</span> active<span style="color:#5bc4bf">)</span>, 0, 192.168.1.1 -&gt; :80, <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 16:37:21 sh1 relayd<span style="color:#5bc4bf">[</span>45869<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">8</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 192.168.1.1 -&gt; :80, <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 16:37:22 sh1 relayd<span style="color:#5bc4bf">[</span>25237<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">14</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 192.168.1.1 -&gt; :80, <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 17:01:19 sh1 relayd<span style="color:#5bc4bf">[</span>45869<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">9</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 207.180.140.98 -&gt; :80, Forbidden <span style="color:#5bc4bf">(</span><span style="color:#f99b15">403</span> Forbidden<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> PHP: none&lt;/em&gt;!, User-Agent: polaris<span style="color:#5bc4bf">]</span> GET: Invalid argument
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 17:01:19 sh1 relayd<span style="color:#5bc4bf">[</span>45869<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">10</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 207.180.140.98 -&gt; :80, <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 17:02:43 sh1 relayd<span style="color:#5bc4bf">[</span>7531<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">13</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 84.161.80.36 -&gt; :80, Forbidden <span style="color:#5bc4bf">(</span><span style="color:#f99b15">403</span> Forbidden<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, Host: 88.136.16.221<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, User-Agent: Mozilla/5.0 <span style="color:#5bc4bf">(</span>Windows NT 10.0; WOW64<span style="color:#5bc4bf">)</span> AppleWebKit/537.36 <span style="color:#5bc4bf">(</span>KHTML, like Gecko<span style="color:#5bc4bf">)</span> Chrome/51.0.2704.103 Safari/537.36<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, 88.136.16.221/phpmyadmin/<span style="color:#5bc4bf">]</span> GET: Invalid argument
</span></span></code></pre></div><p>Cet exemple nous restitue :</p>
<ul>
<li>des connexions réussies <code>done</code></li>
<li>des connexions échouées, ici de type erreur 403, bloquées selon des règles
de filtrage bloquantes <code>block</code> - <em>non expliquées ici</em></li>
</ul>
<h3 id="exemple-log-message">Exemple log message</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ grep relayd /var/log/messages
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 16:22:23 sh1 relayd<span style="color:#5bc4bf">[</span>7531<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">11</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 37.49.230.25 -&gt; :80, Forbidden <span style="color:#5bc4bf">(</span><span style="color:#f99b15">403</span> Forbidden<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> PHP: none&lt;/em&gt;!, User-Agent: Uirusu/2.0<span style="color:#5bc4bf">]</span> GET: Invalid argument
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 17:01:19 sh1 relayd<span style="color:#5bc4bf">[</span>45869<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">9</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 207.180.140.98 -&gt; :80, Forbidden <span style="color:#5bc4bf">(</span><span style="color:#f99b15">403</span> Forbidden<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> PHP: none&lt;/em&gt;!, User-Agent: polaris<span style="color:#5bc4bf">]</span> GET: Invalid argument
</span></span><span style="display:flex;"><span>May <span style="color:#f99b15">17</span> 17:02:43 sh1 relayd<span style="color:#5bc4bf">[</span>7531<span style="color:#5bc4bf">]</span>: relay www, session <span style="color:#f99b15">13</span> <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> active<span style="color:#5bc4bf">)</span>, 0, 84.161.80.36 -&gt; :80, Forbidden <span style="color:#5bc4bf">(</span><span style="color:#f99b15">403</span> Forbidden<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, Host: 88.136.16.221<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, User-Agent: Mozilla/5.0 <span style="color:#5bc4bf">(</span>Windows NT 10.0; WOW64<span style="color:#5bc4bf">)</span> AppleWebKit/537.36 <span style="color:#5bc4bf">(</span>KHTML, like Gecko<span style="color:#5bc4bf">)</span> Chrome/51.0.2704.103 Safari/537.36<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;em&gt;Stop scanning <span style="color:#815ba4">for</span> an admin interface: none&lt;/em&gt;!, 88.136.16.221/phpmyadmin/<span style="color:#5bc4bf">]</span> GET: Invalid argument
</span></span></code></pre></div><p>Cet exemple nous montre 3 écritures de journalisation de règles bloquantes,
provoquant une erreur 403, sur des critères de filtrage non expliqués ici.</p>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/relayd.conf.5" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mettre en place et visualiser la journalisation dans relayd, serveur relai(s) sous OpenBSD]]></summary>
        <published>2020-05-17T13:09:05+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:32994929-231b-f63d-8e2f-fcaf9a687979</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/ovh-over-the-box-v2a/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OVH Over the Box V2A</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OVH" scheme="http://doc.huc.fr.eu.org/fr/tags/ovh/" />
        <category term="Over The Box" scheme="http://doc.huc.fr.eu.org/fr/tags/over-the-box/" />
        <category term="V2A" scheme="http://doc.huc.fr.eu.org/fr/tags/v2a/" />
        <category term="dmesg" scheme="http://doc.huc.fr.eu.org/fr/tags/dmesg/" />
        <category term="sensors" scheme="http://doc.huc.fr.eu.org/fr/tags/sensors/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ici, il n&rsquo;est pas question d&rsquo;installation, mais juste de l&rsquo;aperçu du retour
de <code>dmesg</code> de ce mini-pc fourni par OVH, nommé &ldquo;Over The Box V2A&rdquo;.</p>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openbsd/OVH-OTB-V2A-neofetch-6.8.png" title="Neofetch : OpenBSD 6.8 sur mini-pc OVH Over-the-Box V2A">
    <picture>
        
        <source srcset="/images/openbsd/OVH-OTB-V2A-neofetch-6.8_hu_bea05ea2a809b2d.webp" type="image/webp">
        
        <img alt="Neofetch : OpenBSD 6.8 sur mini-pc OVH Over-the-Box V2A" height="136" loading="lazy" src="/images/openbsd/OVH-OTB-V2A-neofetch-6.8_hu_7533571fab611a2a.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Neofetch : OpenBSD 6.8 sur mini-pc OVH Over-the-Box V2A</figcaption>
</figure>
</div>
<h2 id="dmesg">dmesg</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>OpenBSD 6.8 <span style="color:#5bc4bf">(</span>GENERIC.MP<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#98: Sun Oct  4 18:13:26 MDT 2020</span>
</span></span><span style="display:flex;"><span>    deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2036154368</span> <span style="color:#5bc4bf">(</span>1941MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1959460864</span> <span style="color:#5bc4bf">(</span>1868MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>random: good seed from bootblocks
</span></span><span style="display:flex;"><span>mpath0 at root
</span></span><span style="display:flex;"><span>scsibus0 at mpath0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>mainbus0 at root
</span></span><span style="display:flex;"><span>bios0 at mainbus0: SMBIOS rev. 3.0 @ 0x7b8f3000 <span style="color:#5bc4bf">(</span><span style="color:#f99b15">51</span> entries<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>bios0: vendor American Megatrends Inc. version <span style="color:#48b685">&#34;5.11&#34;</span> date 12/04/2017
</span></span><span style="display:flex;"><span>bios0: OVH SAS Over TheBox V2A
</span></span><span style="display:flex;"><span>acpi0 at bios0: ACPI 5.0
</span></span><span style="display:flex;"><span>acpi0: sleep states S0 S4 S5
</span></span><span style="display:flex;"><span>acpi0: tables DSDT FACP APIC FPDT FIDT MCFG SSDT SSDT SSDT UEFI SSDT HPET SSDT SSDT SSDT LPIT BCFG PRAM BGRT CSRT WDAT
</span></span><span style="display:flex;"><span>acpi0: wakeup devices XHC1<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpitimer0 at acpi0: <span style="color:#f99b15">3579545</span> Hz, <span style="color:#f99b15">24</span> bits
</span></span><span style="display:flex;"><span>acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
</span></span><span style="display:flex;"><span>cpu0 at mainbus0: apid <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>boot processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu0: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Atom<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> x5-Z8350 CPU @ 1.44GHz, 1440.28 MHz, 06-4c-04
</span></span><span style="display:flex;"><span>cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,RDRAND,NXE,RDTSCP,LONG,LAHF,3DNOWP,PERF,ITSC,TSC_ADJUST,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,SENSOR,ARAT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu0: 1MB 64b/line 16-way L2 cache
</span></span><span style="display:flex;"><span>cpu0: smt 0, core 0, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>mtrr: Pentium Pro MTRR support, <span style="color:#f99b15">8</span> var ranges, <span style="color:#f99b15">88</span> fixed ranges
</span></span><span style="display:flex;"><span>cpu0: apic clock running at 79MHz
</span></span><span style="display:flex;"><span>cpu0: mwait <span style="color:#ef6155">min</span><span style="color:#5bc4bf">=</span>64, <span style="color:#ef6155">max</span><span style="color:#5bc4bf">=</span>64, C-substates<span style="color:#5bc4bf">=</span>0.2.0.0.0.0.3.3, IBE
</span></span><span style="display:flex;"><span>cpu1 at mainbus0: apid <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu1: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Atom<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> x5-Z8350 CPU @ 1.44GHz, 1439.96 MHz, 06-4c-04
</span></span><span style="display:flex;"><span>cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,RDRAND,NXE,RDTSCP,LONG,LAHF,3DNOWP,PERF,ITSC,TSC_ADJUST,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,SENSOR,ARAT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu1: 1MB 64b/line 16-way L2 cache
</span></span><span style="display:flex;"><span>cpu1: smt 0, core 1, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>cpu2 at mainbus0: apid <span style="color:#f99b15">4</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu2: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Atom<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> x5-Z8350 CPU @ 1.44GHz, 1439.97 MHz, 06-4c-04
</span></span><span style="display:flex;"><span>cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,RDRAND,NXE,RDTSCP,LONG,LAHF,3DNOWP,PERF,ITSC,TSC_ADJUST,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,SENSOR,ARAT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu2: 1MB 64b/line 16-way L2 cache
</span></span><span style="display:flex;"><span>cpu2: smt 0, core 2, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>cpu3 at mainbus0: apid <span style="color:#f99b15">6</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu3: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Atom<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> x5-Z8350 CPU @ 1.44GHz, 1439.97 MHz, 06-4c-04
</span></span><span style="display:flex;"><span>cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,RDRAND,NXE,RDTSCP,LONG,LAHF,3DNOWP,PERF,ITSC,TSC_ADJUST,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,SENSOR,ARAT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu3: 1MB 64b/line 16-way L2 cache
</span></span><span style="display:flex;"><span>cpu3: smt 0, core 3, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>ioapic0 at mainbus0: apid <span style="color:#f99b15">1</span> pa 0xfec00000, version 20, <span style="color:#f99b15">115</span> pins
</span></span><span style="display:flex;"><span>acpimcfg0 at acpi0
</span></span><span style="display:flex;"><span>acpimcfg0: addr 0xe0000000, bus 0-255
</span></span><span style="display:flex;"><span>acpihpet0 at acpi0: <span style="color:#f99b15">14318179</span> Hz
</span></span><span style="display:flex;"><span>acpiprt0 at acpi0: bus <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>PCI0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt1 at acpi0: bus <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">(</span>RP01<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt2 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP02<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt3 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP03<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt4 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP04<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT33A4&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>chvgpio0 at acpi0 GPO1 uid <span style="color:#f99b15">2</span> addr 0xfed88000/0x8000 irq 48, <span style="color:#f99b15">59</span> pins
</span></span><span style="display:flex;"><span>chvgpio1 at acpi0 GPO3 uid <span style="color:#f99b15">4</span> addr 0xfed98000/0x8000 irq 91, <span style="color:#f99b15">55</span> pins
</span></span><span style="display:flex;"><span>chvgpio2 at acpi0 GPO2 uid <span style="color:#f99b15">3</span> addr 0xfed90000/0x8000 irq 50, <span style="color:#f99b15">24</span> pins
</span></span><span style="display:flex;"><span>chvgpio3 at acpi0 GPO0 uid <span style="color:#f99b15">1</span> addr 0xfed80000/0x8000 irq 49, <span style="color:#f99b15">56</span> pins
</span></span><span style="display:flex;"><span>dwiic0 at acpi0 I2C7 addr 0x91728000/0x1000 irq <span style="color:#f99b15">38</span>
</span></span><span style="display:flex;"><span>iic0 at dwiic0
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT33F4&#34;</span> at iic0 addr 0x34 not configured
</span></span><span style="display:flex;"><span>acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;TXE8086&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3496&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>sdhc0 at acpi0 SDHB addr 0x9173a000/0x1000 irq <span style="color:#f99b15">46</span>
</span></span><span style="display:flex;"><span>sdhc0: SDHC 3.0, <span style="color:#f99b15">200</span> MHz base clock
</span></span><span style="display:flex;"><span>sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed, ddr52, dma
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;RTL8723&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>sdhc1 at acpi0 SDHC addr 0x91738000/0x1000 irq 47, gpio
</span></span><span style="display:flex;"><span>sdhc1: SDHC 3.0, <span style="color:#f99b15">200</span> MHz base clock
</span></span><span style="display:flex;"><span>sdmmc1 at sdhc1: 4-bit, sd high-speed, mmc high-speed, ddr52, dma
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;80862286&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;808622C0&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;80862288&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;80862289&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086228A&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086228A&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;JEHE8888&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086228E&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086228E&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086228E&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>dwiic1 at acpi0 I2C1 addr 0x91734000/0x1000 irq <span style="color:#f99b15">32</span>
</span></span><span style="display:flex;"><span>iic1 at dwiic1
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;TXN27501&#34;</span> at iic1 addr 0x6b not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;TXN24292&#34;</span> at iic1 addr 0x55 not configured
</span></span><span style="display:flex;"><span>dwiic2 at acpi0 I2C2 addr 0x91732000/0x1000 irq <span style="color:#f99b15">33</span>
</span></span><span style="display:flex;"><span>iic2 at dwiic2
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;10EC5670&#34;</span> at iic2 addr 0x1c not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INTCF1D&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;JAHC2333&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;JAHC8563&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>dwiic3 at acpi0 I2C4 addr 0x9172e000/0x1000 irq <span style="color:#f99b15">35</span>
</span></span><span style="display:flex;"><span>iic3 at dwiic3
</span></span><span style="display:flex;"><span>dwiic4 at acpi0 I2C5 addr 0x9172c000/0x1000 irq <span style="color:#f99b15">36</span>
</span></span><span style="display:flex;"><span>iic4 at dwiic4
</span></span><span style="display:flex;"><span>dwiic5 at acpi0 I2C6 addr 0x9172a000/0x1000 irq <span style="color:#f99b15">37</span>
</span></span><span style="display:flex;"><span>iic5 at dwiic5
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;808622A8&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;ADMA22A8&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;TIMC22A8&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;HAD022A8&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpihid0 at acpi0: HIDDacpihid0: exec of HEBC failed
</span></span><span style="display:flex;"><span>acpihid0: exec of HEBC failed
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>acpicmos0 at acpi0
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;JEHE2333&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpibtn0 at acpi0: PWRB
</span></span><span style="display:flex;"><span>chvgpio4 at acpi0 GPO4 uid <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;8086229C&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INTCFD9&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT33BD&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;ACPI000C&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3400&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3403&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3403&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3406&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3403&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpicpu0 at acpi0: C3<span style="color:#5bc4bf">(</span>10@1000 mwait.1@0x64<span style="color:#5bc4bf">)</span>, C2<span style="color:#5bc4bf">(</span>10@500 mwait.1@0x58<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpicpu1 at acpi0: C3<span style="color:#5bc4bf">(</span>10@1000 mwait.1@0x64<span style="color:#5bc4bf">)</span>, C2<span style="color:#5bc4bf">(</span>10@500 mwait.1@0x58<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpicpu2 at acpi0: C3<span style="color:#5bc4bf">(</span>10@1000 mwait.1@0x64<span style="color:#5bc4bf">)</span>, C2<span style="color:#5bc4bf">(</span>10@500 mwait.1@0x58<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpicpu3 at acpi0: C3<span style="color:#5bc4bf">(</span>10@1000 mwait.1@0x64<span style="color:#5bc4bf">)</span>, C2<span style="color:#5bc4bf">(</span>10@500 mwait.1@0x58<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpipwrres0 at acpi0: ID3C, resource <span style="color:#815ba4">for</span> ISP3
</span></span><span style="display:flex;"><span>acpipwrres1 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> HS03, MDM1
</span></span><span style="display:flex;"><span>acpipwrres2 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> HS13, MDM1
</span></span><span style="display:flex;"><span>acpipwrres3 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> SSC1, MDM3
</span></span><span style="display:flex;"><span>acpipwrres4 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> SSCW, MDM3
</span></span><span style="display:flex;"><span>acpipwrres5 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> HSC1, MDM2
</span></span><span style="display:flex;"><span>acpipwrres6 at acpi0: WWPR, resource <span style="color:#815ba4">for</span> HSC3, MDM4
</span></span><span style="display:flex;"><span>acpipwrres7 at acpi0: CLK3, resource <span style="color:#815ba4">for</span> RTEK, RTK1
</span></span><span style="display:flex;"><span>acpipwrres8 at acpi0: CLK4
</span></span><span style="display:flex;"><span>acpipwrres9 at acpi0: CLK2, resource <span style="color:#815ba4">for</span> NFC2
</span></span><span style="display:flex;"><span>acpipwrres10 at acpi0: CLK1
</span></span><span style="display:flex;"><span>acpipwrres11 at acpi0: CLK0
</span></span><span style="display:flex;"><span>acpipwrres12 at acpi0: CLK1
</span></span><span style="display:flex;"><span>acpipwrres13 at acpi0: USBC, resource <span style="color:#815ba4">for</span> XHC1, OTG1
</span></span><span style="display:flex;"><span>acpipwrres14 at acpi0: P28X
</span></span><span style="display:flex;"><span>acpipwrres15 at acpi0: P18X
</span></span><span style="display:flex;"><span>acpipwrres16 at acpi0: P12X
</span></span><span style="display:flex;"><span>acpipwrres17 at acpi0: P28P
</span></span><span style="display:flex;"><span>acpipwrres18 at acpi0: P18P
</span></span><span style="display:flex;"><span>acpipwrres19 at acpi0: P19X
</span></span><span style="display:flex;"><span>acpipwrres20 at acpi0: P06X
</span></span><span style="display:flex;"><span>acpipwrres21 at acpi0: P12A
</span></span><span style="display:flex;"><span>acpipwrres22 at acpi0: P28T
</span></span><span style="display:flex;"><span>acpipwrres23 at acpi0: P18D
</span></span><span style="display:flex;"><span>acpipwrres24 at acpi0: P18T
</span></span><span style="display:flex;"><span>acpipwrres25 at acpi0: P3P3
</span></span><span style="display:flex;"><span>acpipwrres26 at acpi0: P12T
</span></span><span style="display:flex;"><span>acpipwrres27 at acpi0: P28W
</span></span><span style="display:flex;"><span>acpipwrres28 at acpi0: P18W
</span></span><span style="display:flex;"><span>acpipwrres29 at acpi0: P12W
</span></span><span style="display:flex;"><span>acpipwrres30 at acpi0: P33W
</span></span><span style="display:flex;"><span>acpipwrres31 at acpi0: P33X
</span></span><span style="display:flex;"><span>acpipwrres32 at acpi0: P4BW
</span></span><span style="display:flex;"><span>acpitz0 at acpi0: critical temperature is <span style="color:#f99b15">90</span> degC
</span></span><span style="display:flex;"><span>acpivideo0 at acpi0: GFX0
</span></span><span style="display:flex;"><span>acpivout0 at acpivideo0: DD01
</span></span><span style="display:flex;"><span>acpivout1 at acpivideo0: DD02
</span></span><span style="display:flex;"><span>acpivout2 at acpivideo0: DD03
</span></span><span style="display:flex;"><span>acpivout3 at acpivideo0: DD04
</span></span><span style="display:flex;"><span>acpivout4 at acpivideo0: DD05
</span></span><span style="display:flex;"><span>acpivout5 at acpivideo0: DD06
</span></span><span style="display:flex;"><span>acpivout6 at acpivideo0: DD07
</span></span><span style="display:flex;"><span>acpivout7 at acpivideo0: DD08
</span></span><span style="display:flex;"><span>cpu0: using VERW MDS workaround
</span></span><span style="display:flex;"><span>cpu0: Enhanced SpeedStep <span style="color:#f99b15">1440</span> MHz: speeds: 1920, 1840, 1760, 1680, 1600, 1520, 1440, 1360, 1280, 1200, 1120, 1040, 960, 880, 800, 720, 640, 560, <span style="color:#f99b15">480</span> MHz
</span></span><span style="display:flex;"><span>pci0 at mainbus0 bus <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pchb0 at pci0 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Braswell Host&#34;</span> rev 0x36
</span></span><span style="display:flex;"><span>inteldrm0 at pci0 dev <span style="color:#f99b15">2</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel HD Graphics&#34;</span> rev 0x36
</span></span><span style="display:flex;"><span>drm0 at inteldrm0
</span></span><span style="display:flex;"><span>inteldrm0: msi, CHERRYVIEW, gen <span style="color:#f99b15">8</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Intel Braswell Power&#34;</span> rev 0x36 at pci0 dev <span style="color:#f99b15">11</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>sdhc2 at pci0 dev <span style="color:#f99b15">16</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> vendor <span style="color:#48b685">&#34;Intel&#34;</span>, unknown product 0x2294 rev 0x36: apic <span style="color:#f99b15">1</span> int <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>sdhc2: SDHC 3.0, <span style="color:#f99b15">200</span> MHz base clock
</span></span><span style="display:flex;"><span>sdmmc2 at sdhc2: 8-bit, sd high-speed, mmc high-speed, ddr52, dma
</span></span><span style="display:flex;"><span>xhci0 at pci0 dev <span style="color:#f99b15">20</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Braswell xHCI&#34;</span> rev 0x36: msi, xHCI 1.0
</span></span><span style="display:flex;"><span>usb0 at xhci0: USB revision 3.0
</span></span><span style="display:flex;"><span>uhub0 at usb0 configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel xHCI root hub&#34;</span> rev 3.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Intel Braswell USB OTG&#34;</span> rev 0x36 at pci0 dev <span style="color:#f99b15">22</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Intel Braswell TXE&#34;</span> rev 0x36 at pci0 dev <span style="color:#f99b15">26</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>ppb0 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Braswell PCIE&#34;</span> rev 0x36: msi
</span></span><span style="display:flex;"><span>pci1 at ppb0 bus <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>re0 at pci1 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Realtek 8168&#34;</span> rev 0x07: RTL8168E/8111E-VL <span style="color:#5bc4bf">(</span>0x2c80<span style="color:#5bc4bf">)</span>, msi, address 24:1c:04:08:8c:05
</span></span><span style="display:flex;"><span>rgephy0 at re0 phy 7: RTL8169S/8110S/8211 PHY, rev. <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>pcib0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Braswell PCU LPC&#34;</span> rev 0x36
</span></span><span style="display:flex;"><span>isa0 at pcib0
</span></span><span style="display:flex;"><span>isadma0 at isa0
</span></span><span style="display:flex;"><span>com0 at isa0 port 0x3f8/8 irq 4: ns16550a, <span style="color:#f99b15">16</span> byte fifo
</span></span><span style="display:flex;"><span>com1 at isa0 port 0x2f8/8 irq 3: ns8250, no fifo
</span></span><span style="display:flex;"><span>com2 at isa0 port 0x3e8/8 irq 5: ns8250, no fifo
</span></span><span style="display:flex;"><span>pckbc0 at isa0 port 0x60/5 irq <span style="color:#f99b15">1</span> irq <span style="color:#f99b15">12</span>
</span></span><span style="display:flex;"><span>pckbd0 at pckbc0 <span style="color:#5bc4bf">(</span>kbd slot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wskbd0 at pckbd0: console keyboard
</span></span><span style="display:flex;"><span>pcppi0 at isa0 port 0x61
</span></span><span style="display:flex;"><span>spkr0 at pcppi0
</span></span><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT <span style="color:#5bc4bf">(</span>using slow L1TF mitigation<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>efifb at mainbus0 not configured
</span></span><span style="display:flex;"><span>sdmmc0: can<span style="color:#48b685">&#39;t enable card
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">sdmmc1: can&#39;</span>t enable card
</span></span><span style="display:flex;"><span>scsibus1 at sdmmc2: <span style="color:#f99b15">2</span> targets, initiator <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>sd0 at scsibus1 targ <span style="color:#f99b15">1</span> lun 0: &lt;Samsung, 8GME4R, 0000&gt; removable
</span></span><span style="display:flex;"><span>sd0: 7456MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">15269888</span> sectors
</span></span><span style="display:flex;"><span>umass0 at uhub0 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;ASMedia AS2115&#34;</span> rev 2.10/0.01 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>umass0: using SCSI over Bulk-Only
</span></span><span style="display:flex;"><span>scsibus2 at umass0: <span style="color:#f99b15">2</span> targets, initiator <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>sd1 at scsibus2 targ <span style="color:#f99b15">1</span> lun 0: &lt;ASMT, 2115, 0&gt; serial.174c1153000000000000
</span></span><span style="display:flex;"><span>sd1: 122104MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">250069680</span> sectors
</span></span><span style="display:flex;"><span>uhub1 at uhub0 port <span style="color:#f99b15">4</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Genesys Logic USB2.0 Hub&#34;</span> rev 2.00/85.36 addr <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>vscsi0 at root
</span></span><span style="display:flex;"><span>scsibus3 at vscsi0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>softraid0 at root
</span></span><span style="display:flex;"><span>scsibus4 at softraid0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>root on sd0a <span style="color:#5bc4bf">(</span>2f18100544c5d963.a<span style="color:#5bc4bf">)</span> swap on sd0b dump on sd0b
</span></span><span style="display:flex;"><span>inteldrm0: 1024x768, 32bpp
</span></span><span style="display:flex;"><span>wsdisplay0 at inteldrm0 mux 1: console <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>, using wskbd0
</span></span><span style="display:flex;"><span>wsdisplay0: screen 1-5 added <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h2 id="hwsensors">hw.sensors</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$  sysctl hw.sensors  
</span></span><span style="display:flex;"><span>hw.sensors.cpu0.temp0<span style="color:#5bc4bf">=</span>43.00 degC
</span></span><span style="display:flex;"><span>hw.sensors.acpitz0.temp0<span style="color:#5bc4bf">=</span>0.00 degC <span style="color:#5bc4bf">(</span>zone temperature<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Aperçu de dmesg sur le mini-pc OVH Over the Box V2A]]></summary>
        <published>2020-05-14T16:57:10+02:00</published>
        <updated>2023-04-30T17:05:08+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:83199337-66a8-85a8-23c4-32183efcc3cc</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/dino/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Dino (client XMPP)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Dino" scheme="http://doc.huc.fr.eu.org/fr/tags/dino/" />
        <category term="XMPP" scheme="http://doc.huc.fr.eu.org/fr/tags/xmpp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Dino est un client de communication chat moderne et open-source, sous X.
Il se concentre sur le fait de fournir une expérience propre et fiable
Jabber/XMPP tout en gardant à l&rsquo;esprit votre confidentialité.</p>
<p>Dino est sécurisé par défaut : vos communications sont toujours chiffrées.
Une fois que vous avez activé le chiffrement de bout à bout via OMEMO ou
OpenPGP, seuls vous et vos correspondants peuvent lire vos messages, pas
même un administrateur de serveurs.</p>
<ul>
<li>Site officiel : <a href="http://dino.im/" rel="external">http://dino.im/</a></li>
</ul>
<p>Disponible : à partir d&rsquo;OpenBSD 6.7</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>dino</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>La première chose que demande Dino est sa configuration. Un clic sur le
gros bouton rouge [ Configurer le compte ] permet soit de configurer un
nouveau compte XMPP, soit de se connecter à un compte existant.</p>
<p>Une fenêtre titrée &ldquo;Ajouter un compte&rdquo; s&rsquo;ouvre, et vous demande un
<abbr title="Jabber IDentifiant">JID</abbr>
 - un Identifiant Jabber.</p>
<ul>
<li>Si vous n&rsquo;avez pas de compte Jabber, cliquez sur le bouton
[ Créer un compte ]</li>
<li>Si vous avez un compte Jabber, écrivez-le dans le champ JID ; le
bouton [ Suivant ] s&rsquo;activera. Cliquez dessus, la fenêtre vous
demandera le mot de passe correspondant. Une fois la connexion achevée,
la fenêtre vous félicitera avec un message &ldquo;Terminé&rdquo;.</li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<p>La fenêtre est très minimaliste. Les menus sont situés dans le haut de
la fenêtre sous forme de symbole.</p>
<p>En haut à gauche :</p>
<ul>
<li><code>+</code> : permet de choisir les menus <strong>Commencer une conversation</strong> et
<strong>Rejoindre un salon</strong></li>
<li>le symbole en forme de trois barres parallèles horizontales est le
menu principal et sert à gérer les comptes, les préférences,
principalement.</li>
</ul>
<p>En haut à droite :</p>
<ul>
<li>l&rsquo;icône en forme de deux personnes : active la fenêtre pour voir les
différents membres d&rsquo;un salon ; celle-ci n&rsquo;est visible que sur les
salons.</li>
<li>l&rsquo;icône de recherche : pour rechercher différents messages dans les
différents fils de discussion.</li>
<li>et le deuxième symbole de menu en forme de trois barres parallèles :
<ul>
<li>soit donne accès aux détails du salon,</li>
<li>soit donne les détails liés à votre interlocuteur.</li>
</ul>
</li>
</ul>
<p><em>(à suivre)</em></p>
<h2 id="documentation">Documentation</h2>
<p>⇒ Articles :</p>
<ul>
<li><a href="https://dino.im/blog/2020/01/dino-0.1-release/" rel="external">présentation officielle</a>,</li>
<li>et <a href="https://news.jabberfr.org/2020/01/release-de-dino-0-1/" rel="external">traduction FR</a>.</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement de manière collaborative cette documentation
sur le wiki de la communauté  &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le client XMMP, nommé Dino, sous OpenBSD]]></summary>
        <published>2020-05-13T16:08:31+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5fcc6bb2-262a-53da-63dd-6a03e26951ef</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/httpd/relayd-cache-httpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Relayd : Mise en cache web pour httpd</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="relayd" scheme="http://doc.huc.fr.eu.org/fr/tags/relayd/" />
        <category term="Cache" scheme="http://doc.huc.fr.eu.org/fr/tags/cache/" />
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base, depuis 5.7 :</p>
<ul>
<li>
<p>un serveur web, nommé <strong>httpd</strong> - que j&rsquo;ai présenté plus ou moins
succinctement 
<a class="inside" href="/fr/web/httpd/httpd/" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">ici</a>
</p>
</li>
<li>
<p>un serveur relay, nommé <strong>relayd</strong></p>
</li>
<li>
<p>Site web : <a href="https://bsd.plumbing/" rel="external">https://bsd.plumbing/</a></p>
</li>
<li>
<p>OpenBSD : <strong>6.6, 6.7</strong></p>
</li>
</ul>
<hr>
<p>Le problème est que le serveur <strong>httpd</strong> n&rsquo;est pas capable de gérer la
mise en cache de contenu statique.</p>
<p>Nous passons donc le relais au serveur <strong>relayd</strong> qui lui en est capable -
<em>par contre, il le fait de manière globale, <abbr title="c'est-à-dire">çad</abbr>

non spécifique à un domaine en particulier</em> -</p>
<h2 id="configuration">Configuration</h2>
<p>Les explications de configuration du serveur <strong>httpd</strong> ont été abordés
sur cet autre article : <a class="inside" href="/fr/web/httpd/relayd-headers-httpd/#httpd" title="Lien interne vers l&#39;article : 'Relayd : Gestion des entêtes pour httpd'">Relayd : Gestion des entêtes pour httpd</a> <br>
<em>(cf : <a class="inside" href="/fr/web/httpd/relayd-headers-httpd/#httpd-exemple" title="Lien interne vers l&#39;article : 'Relayd : Gestion des entêtes pour httpd'">l'exemple de configuration</a>
)</em></p>
<p>C&rsquo;est exactement le même principe.</p>
<h3 id="relayd">relayd</h3>
<ul>
<li>Le fichier de configuration est <code>/etc/relayd.conf</code>, par défaut.</li>
</ul>
<p>Dans le contexte du protocole http, en lui donnant un nom - <em>le nom importe
peu, mais est réutilisé plus tard, dans le contexte des déclarations
de relais</em> :</p>
<ul>
<li>nous ciblons tous les fichiers contenant normalement du contenu statique,
en analysant les requêtes - <br>
c&rsquo;est généralement le cas pour les fichiers, tels que :
<ul>
<li>les images (GIF, JPG, PNG, SVG)</li>
<li>les fichiers CSS et JS,</li>
<li>et les fichiers HTML, et XML (Atom, RSS, etc).</li>
</ul>
</li>
<li>nous leur appliquons une politique d&rsquo;étiquetage, par l&rsquo;usage de l&rsquo;option <code>tag</code>.
<em>Là, encore le nom donné importe peu pourvu que vous réutilisiez le même
dans le cadre de l&rsquo;entête <code>header</code> de réponse.</em></li>
<li>puis nous retournons une entête de réponse <code>Cache-Control</code> ciblant l&rsquo;étiquette.</li>
</ul>
<p>Puis nous appliquons le protocole http déclaré a un relay cible.</p>
<h4 id="relayd--exemple">relayd : exemple</h4>
<pre tabindex="0"><code>ip4 = &#34;public-address-ipv4&#34;

http protocol &#34;hw&#34; {

    match request path &#34;/*.atom&#34; tag &#34;CACHE&#34;
    match request path &#34;/*.css&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.gif&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.html&#34; tag &#34;CACHE&#34;
    match request path &#34;/*.ico&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.jpg&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.js&#34;   tag &#34;CACHE&#34;
    match request path &#34;/*.png&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.rss&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.svg&#34;  tag &#34;CACHE&#34;
    match request path &#34;/*.xml&#34;  tag &#34;CACHE&#34;

    match response tagged &#34;CACHE&#34; header set &#34;Cache-Control&#34; value &#34;public, max-age=86400&#34;

    tcp { nodelay, sack, socket buffer 65536, backlog 100 }

    pass

}

relay &#34;www&#34; {
    listen on $ip4 port 80
    protocol hw
    forward to 127.0.0.1 port 80
}
</code></pre><h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/httpd.conf.5" title="Page du Manuel OpenBSD pour : httpd.conf">httpd.conf(5)</a>
</li>
</ul>
<h3 id="autres-documentations">Autres documentations</h3>
<ul>
<li><del>L&rsquo;article de Xavier Cartron @prx : <strong>&quot;<a href="https://ybad.name/ah/doku.php/4-httpd/relayd#optimisation-du-cache-et-de-la-bande-passante" rel="external">Optimisation du cache et de la bande passante</a>&quot;</strong></del></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place du cache de contenu statique avec httpd &amp; relayd, serveurs natifs sous OpenBSD]]></summary>
        <published>2020-05-07T16:49:36+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4ac2b6ae-2cc2-f212-f092-b915baacde23</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/httpd/relayd-headers-httpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Relayd : Gestion des entêtes pour httpd</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="relayd" scheme="http://doc.huc.fr.eu.org/fr/tags/relayd/" />
        <category term="Header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base, depuis 5.7 :</p>
<ul>
<li>
<p>un serveur web, nommé <strong>httpd</strong> - que j&rsquo;ai présenté plus ou moins
succinctement 
<a class="inside" href="/fr/web/httpd/httpd/" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">ici</a>
</p>
</li>
<li>
<p>un serveur relay, nommé <strong>relayd</strong></p>
</li>
<li>
<p>Site web : <a href="https://bsd.plumbing/" rel="external">https://bsd.plumbing/</a></p>
</li>
<li>
<p>OpenBSD : <strong>6.6, 6.7</strong></p>
</li>
</ul>
<hr>
<p>Le problème est que le serveur <strong>httpd</strong> n&rsquo;est pas capable de gérer les
entêtes <abbr title="HyperText Transfert Protocol">HTTP</abbr>
 <em>(en anglais : <a class="tag" href="/fr/tags/header">header</a>
)</em>,
et que <a href="https://marc.info/?l=openbsd-misc&amp;m=142407262812306&amp;w=2" rel="external">l&rsquo;auteur ne le veut pas</a>.</p>
<p>Nous passons donc le relais au serveur <strong>relayd</strong> qui lui est capable de
les gérer - <em>par contre, il le fait de manière globale, <abbr title="c'est-à-dire">çad</abbr>

non spécifique à un domaine en particulier</em> -</p>
<h2 id="configuration">Configuration</h2>
<p>Étant donné que <strong>relayd</strong> est en frontal d&rsquo;<strong>httpd</strong>, nous allons modifier
la configuration des deux fichiers de configuration relatifs.</p>
<ul>
<li><strong>relayd</strong> va recevoir tout le traffic à destination des ports web, 80,
voire 443, si <abbr title="Transport Layer Secure">TLS</abbr>
 et le rediriger
en local sur les ports correspondant. Bien sûr, il est possible d&rsquo;agir
sur chacune des piles réseaux des protocoles IPv4 et IPv6.</li>
<li>quant à lui, <strong>httpd</strong> ne fera qu&rsquo;interroger la boucle locale sur les
ports redirigés.</li>
</ul>
<p>Ne pas oublier de redémarrer les services correspondants après modifier
de la configuration !</p>
<h3 id="httpd">httpd</h3>
<ul>
<li>Le fichier de configuration est <code>/etc/httpd.conf</code>, par défaut.</li>
</ul>
<p>Dans le contexte <code>server</code>, il y a deux, trois modifications importantes à
faire :</p>
<ul>
<li>l&rsquo;option d&rsquo;écoute <code>listen on</code> doit écouter localhost - <em>cf : <a href="https://man.openbsd.org/httpd.conf#listen" rel="external">listen on</a></em></li>
<li>l&rsquo;option de journalisation <code>log</code> est à modifier pour que le <code>style</code> soit
paramétré sur <code>forwarder</code> - <em>cf : <a href="https://man.openbsd.org/httpd.conf#style" rel="external">style</a></em></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Sachez que certains écrivent une redirection vers le port 8080, au lieu de 80.
Bien-sûr, cela fonctionne ; c&rsquo;est à votre convenance.</div>

<p>Seule l&rsquo;entête <abbr title="HTTP Strict Transport Security">HSTS</abbr>
 est géré différement :</p>
<h4 id="httpd-hsts">httpd: HSTS</h4>
<p>L&rsquo;entête <strong>HSTS</strong> se modifie, non pas en déclarant une entête, comme pour les
autres, mais en utilisant tout simplement l&rsquo;option <code>hsts</code> <em>(cf : <a href="https://man.openbsd.org/httpd.conf#hsts" rel="external">hsts</a>)</em>.</p>
<p>Elle se gère bien sûr dans le contexte de protocole
<abbr title="HyperText Transport Protocol Secure">HTTPS</abbr>
,
via <abbr title="Transport Layer Secure">TLS</abbr>
.</p>
<p><em>Pour l&rsquo;instant, nous n&rsquo;aborderons pas ce sujet ; d&rsquo;autant que je fais les
présentations dans mon article de <a class="inside" href="/fr/web/httpd/httpd/#tls" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">présentation d'httpd</a>
.</em></p>
<h4 id="httpd-exemple">httpd: exemple</h4>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">server &#34;domain.tld&#34; {

    listen on 127.0.0.1 port 80
    listen on ::1 port 80

    # enable hsts only if you use TLS for HTTPS
    hsts {
        max-age 63072000
        preload
        subdomains
    }

    location &#34;/.well-known/acme-challenge/*&#34; {
        root &#34;/acme&#34;
        request strip 2
    }

    location &#34;/&#34; {
        directory index index.html
    }

    log {
        access &#34;domain.tld/access.log&#34;
        error  &#34;domain.tld/errors.log&#34;
        style forwarded
    }

    root &#34;/htdocs/domain.tld/www&#34;
}
</code></pre><h4 id="httpd-log">httpd: log</h4>
<p>Voici un exemple de log :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">domain.tld 127.0.0.1 - - [06/May/2020:04:08:51 +0200] &#34;GET / HTTP/1.1&#34; 200 0 &#34;&#34; &#34;Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)&#34; 66.249.79.202 -
domain.tld 127.0.0.1 - - [06/May/2020:09:48:36 +0200] &#34;GET /robots.txt HTTP/1.1&#34; 200 0 &#34;&#34; &#34;Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)&#34; 5.196.87.174 -
domain.tld 127.0.0.1 - - [06/May/2020:10:29:29 +0200] &#34;GET / HTTP/1.1&#34; 200 0 &#34;&#34; &#34;Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)&#34; 54.36.148.31 -
</code></pre><p>Nous remarquons bien que l&rsquo;adresse IP du client est précisé en fin de ligne. <br>
C&rsquo;est ce que permet le paramètre de style de journal <code>forwarder</code>.</p>
<h3 id="relayd">relayd</h3>
<ul>
<li>Le fichier de configuration est <code>/etc/relayd.conf</code>, par défaut.</li>
</ul>
<p>Dans les faits :</p>
<ul>
<li>Nous déclarons un protocole <strong>http</strong> en lui donnant un nom - <em>le nom importe
peu, mais est réutilisé plus tard, dans le contexte des déclarations
de relais</em>.</li>
<li>les filtres de correspondance <code>match</code> pour créer les réponses d&rsquo;entêtes <code>header</code>.
<ul>
<li>les deux premières déclarations sont nécessaires pour capturer les
valeurs serveurs suivantes afin de les rediriger correctement :
<ul>
<li><code>$SERVER_ADDR:$SERVER_PORT</code> pour l&rsquo;option <code>X-Forwarded-By</code>,</li>
<li><code>$REMOTE_ADDR</code> pour l&rsquo;option <code>X-Forwarded-For</code>.</li>
</ul>
</li>
</ul>
</li>
<li>puis nous relaierons en paramétrant, dans les déclarations <code>relay</code> correspondantes :
<ul>
<li>l&rsquo;option d&rsquo;écoute <code>listen</code>, sur l&rsquo;adresse IP public et le port www et,</li>
<li>nous ciblons le protocole <strong>http</strong> nommé afin que les règles sur les
entêtes soient appliquées dans chacun des contextes de relais, et,</li>
<li>redirigerons à l&rsquo;aide de l&rsquo;option <code>forward</code> vers l&rsquo;interface de bouclage
local, et le port désiré, correspondant à celui sur lequel écoute
<strong>httpd</strong>.</li>
</ul>
</li>
</ul>
<h4 id="relayd-httpoxy">relayd: Httpoxy</h4>
<p>Certains des plus attentifs remarqueront dans l&rsquo;exemple ci-dessous la déclaration
de l&rsquo;entête suivante : \</p>
<p><code>match request header remove &quot;Proxy&quot;</code></p>
<p>Celle-ci est utile pour lutter contre la faille <strong><a href="https://httpoxy.org/" rel="external">Httpoxy</a></strong> qui affecte
les applications CGI, PHP, dans le contexte d&rsquo;une connexion <abbr title="HyperText Transfert Protocol">HTTP</abbr>
.</p>
<p>C&rsquo;est reconnue comme étant la meilleure façon de bloquer cette faille. <br>
L&rsquo;autre angle de protection efficace est de fournir des connexions <abbr title="HyperText Transfert Protocol Secure">HTTPS</abbr>
,
qui apparemment ne sont pas assujetties à cette faille.</p>
<h4 id="relayd-exemple">relayd: exemple</h4>
<pre tabindex="0"><code>ip4 = &#34;ipv4_public_address&#34;
ip6 = &#34;ipv6_public_address&#34;

http protocol &#34;hw&#34; {
    match request header set &#34;X-Forwarded-By&#34;   value &#34;$SERVER_ADDR:$SERVER_PORT&#34;
    match request header set &#34;X-Forwarded-For&#34;  value &#34;$REMOTE_ADDR&#34;

    match request header remove &#34;Proxy&#34;

    match response header set &#34;Cache-Control&#34;           value &#34;max-age=1814400&#34;
    match response header set &#34;Content-Security-Policy&#34; value &#34;upgrade-insecure-requests; default-src https: &#39;self&#39;&#34;
    match response header set &#34;Permissions-Policy&#34;      value &#34;fullscreen=(), geolocation=(), microphone()&#34;
    match response header set &#34;Frame-Options&#34;           value &#34;SAMEORIGIN&#34;
    match response header set &#34;Referrer-Policy&#34;         value &#34;strict-origin&#34;
    match response header set &#34;Server&#34;                  value &#34;OpenBSD Relayd+httpd&#34;

    match response header set &#34;X-Content-Type-Options&#34; value &#34;nosniff&#34;
    match response header set &#34;X-Download-Options&#34;     value &#34;noopen&#34;
    match response header set &#34;X-Frame-Options&#34;        value &#34;SAMEORIGIN&#34;
    match response header set &#34;X-Powered-By&#34;           value &#34;!&#34;
    match response header set &#34;X-Robots-Tag&#34;           value &#34;index, nofollow&#34;
    match response header set &#34;X-Xss-Protection&#34;       value &#34;1; mode=block&#34;

    tcp { nodelay, sack, socket buffer 65536, backlog 100 }

    pass
}

relay &#34;www&#34; {
    listen on $ip4 port 80
    protocol hw
    forward to 127.0.0.1 port 80
}

relay &#34;www6&#34; {
    listen on $ip6 port 80
    protocol hw
    forward to ::1 port 80
}
</code></pre><h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/httpd.conf.5" title="Page du Manuel OpenBSD pour : httpd.conf">httpd.conf(5)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/relayd.conf.5" title="Page du Manuel OpenBSD pour : relayd.conf">relayd.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/relayctl.8" title="Page du Manuel OpenBSD pour : relayctl">relayctl(8)</a>
</li>
</ul>
<h3 id="autres-documentations">Autres documentations</h3>
<ul>
<li>Pour en savoir plus sur les entêtes :
<ul>
<li><strong>Content-Security-Policy</strong> : 
<a class="inside" href="/fr/web/http/csp/" title="Lien interne vers l&#39;article : 'CSP : Content Security Policy (header)'">CSP : Content Security Policy (header)</a>

</li>
<li><strong>Cross-origin Resource Sharing</strong> : 
<a class="inside" href="/fr/web/http/cors/" title="Lien interne vers l&#39;article : 'CORS : Cross-origin Resource Sharing (header)'">CORS : Cross-origin Resource Sharing (header)</a>

</li>
<li><strong>Frame-Options</strong> : 
<a class="inside" href="/fr/web/http/x-frame-options/" title="Lien interne vers l&#39;article : 'X-Frame-Options (header)'">X-Frame-Options (header)</a>

</li>
<li><strong>HSTS</strong> : 
<a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS : HTTP Strict Transport Security (header)</a>

</li>
<li><strong>Referrer</strong> : 
<a class="inside" href="/fr/web/http/referrer/" title="Lien interne vers l&#39;article : 'HTTP : Referrer (header)'">HTTP : Referrer (header)</a>

</li>
<li><strong>X-Content-Type-Options</strong> : 
<a class="inside" href="/fr/web/http/x-content-type-options/" title="Lien interne vers l&#39;article : 'X-Content-Type-Options (header)'">X-Content-Type-Options (header)</a>

</li>
<li><strong>X-Frame-Options</strong> : 
<a class="inside" href="/fr/web/http/x-frame-options/" title="Lien interne vers l&#39;article : 'X-Frame-Options (header)'">X-Frame-Options (header)</a>

</li>
<li><strong>X-Xss-Protection</strong> : 
<a class="inside" href="/fr/web/http/x-xss-protection/" title="Lien interne vers l&#39;article : 'X-XSS-Protection (header)'">X-XSS-Protection (header)</a>

</li>
</ul>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment gérer les entêtes HTTP avec le couple serveur relay&#43;web, httpd &amp; relayd, serveurs natifs sous OpenBSD]]></summary>
        <published>2020-05-06T15:00:23+02:00</published>
        <updated>2020-05-07T18:20:36+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:02b7463e-a296-2a32-21e5-d00c5c64100e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/devuan/opensmtpd-client-auth/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Devuan : Opensmtpd Client Auth</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Devuan" scheme="http://doc.huc.fr.eu.org/fr/tags/devuan/" />
        <category term="OpenSMPTD" scheme="http://doc.huc.fr.eu.org/fr/tags/opensmptd/" />
        <category term="smtp" scheme="http://doc.huc.fr.eu.org/fr/tags/smtp/" />
        <category term="client" scheme="http://doc.huc.fr.eu.org/fr/tags/client/" />
        <category term="mail" scheme="http://doc.huc.fr.eu.org/fr/tags/mail/" />
        <category term="auth" scheme="http://doc.huc.fr.eu.org/fr/tags/auth/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenSMTPD</strong> est une libre implémentation du protocole SMTP tel que défini dans
la <a href="https://www.rfc-editor.org/info/rfc5321" title="RFC Editor : Information à-propos de la RFC 5321">RFC 5321</a>
, avec quelques extensions standards additionnels. <br>
Il permet à des machines ordinaire d&rsquo;échanger des mails avec d&rsquo;autres systèmes
&ldquo;parlant&rdquo; le protocole 





















































































<abbr lang="en" title="Simple Mail Transfer Protocol">SMTP</abbr>


























.</p>
<p><strong>OpenSMTPD</strong> fait partie du système de base du système d&rsquo;exploitation
OpenBSD. Il a été &ldquo;porté&rdquo; sur d&rsquo;autres OS, tel Devuan.</p>
<p>Informations :</p>
<ul>
<li>Site web : <a href="https://www.opensmtpd.org" rel="external">https://www.opensmtpd.org</a></li>
</ul>
<hr>
<p><abbr title="Question">Q</abbr>
 : <strong>Pourquoi utiliser OpenSMTPD ?</strong></p>
<p>Parce qu&rsquo;OpenSMTPD est :</p>
<ul>
<li><strong>facile à <a href="/fr/sys/devuan/opensmtpd-client-auth/#configuration">configurer</a></strong> : un seul fichier texte !</li>
<li>reconnu comme étant fiable ET sécurisé.</li>
</ul>
<hr>
<p>Fonctionnel et testé sur :</p>
<ul>
<li>Debian Sid, Devuan Ceres</li>
<li>Linux Mint</li>
</ul>
<h2 id="installation">Installation</h2>
<p><code>apt install opensmtpd</code></p>
<ul>
<li>le journal se trouve être : <code>/var/log/mail.log</code></li>
</ul>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration principal est : <code>/etc/smtpd.conf</code></li>
</ul>
<p>Pour envoyer un mail par 





















































































<abbr lang="en" title="Simple Mail Transfer Protocol">SMTP</abbr>


























 à un service de mails nécessitant
une identification, il est nécessaire de créer dans un premier temps, un fichier
<code>secrets</code> avec les droits adéquats sur votre système, ensuite il nous reste à
configurer le fichier <code>smtpd.conf</code>.</p>
<h3 id="fichier-secrets">Fichier secrets</h3>
<p>Création du fichier de secrets :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ mkdir -p .config/mail
</span></span><span style="display:flex;"><span>:$ touch .config/mail/secrets
</span></span><span style="display:flex;"><span>:$ chmod <span style="color:#f99b15">0640</span> .config/mail/secrets
</span></span></code></pre></div><p>Ensuite, il est nécessaire de le remplir de telle manière : <br>
<code>identifiant username:password</code></p>
<p><span class="red">n'écrivez pas TEXTUELLEMENT cette information</span>
,
remplacez-là par les informations ci-dessous :</p>
<ul>
<li>où <code>identifiant</code> est l&rsquo;identifiant que vous choisissez soigneusement,
et qui vous servira plus tard dans la configuration du fichier
<code>smtpd.conf</code> ;</li>
<li><code>username</code> est votre identifiant de connexion mail au service mail de
votre fournisseur - <em>généralement votre adresse mail</em> - ;</li>
<li><code>password</code> étant le mot de passe lié à votre identification mail.</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est possible de nommer autrement ce fichier secrets, et de le mettre
ailleurs dans votre système de fichier ; comprenez-le principe et
modifier en conséquence.</p>
<p>De même, je vous encourage fortement à ne mettre QUE des droits <strong>0440</strong>
sur le fichier - <em>par défaut : 0640</em>.</p>
<p>Même si l&rsquo;accès au fichier par smtpd peut sans soucis être fait avec vos
droits personnels <code>$USER:$USER</code>, il est préférable de mettre à minima les
droits du groupe <code>opensmtpd</code>.</p>
<pre tabindex="0"><code>:# chown $USER:opensmtpd .config/mail/secrets
:$ chmod 0440 .config/mail/secrets
</code></pre><hr>
<p><strong>Note à-propos d&rsquo;un home chiffré</strong> : veillez absolument à copier/déplacer
ce fichier vers /etc/mail/, autrement le service correspondant ne démarrera
pas, puisqu&rsquo;il ne peut/pourra pas avoir accès au fichier à ce moment-là !</p>
</div>

<h3 id="fichier-smtpdconf">Fichier smtpd.conf</h3>
<p>Maintenant modifions le fichier <code>/etc/smtpd.conf</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#   $OpenBSD: smtpd.conf,v 1.10 2018/05/24 11:40:17 gilles Exp $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># This is the smtpd server system-wide configuration file.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See smtpd.conf(5) for more information.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table aliases file:/etc/aliases</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table secrets file:/home/votre-id/.config/mail/secrets</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue compression</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># To accept external mail, replace with: listen on all</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen on localhost</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">action &#34;local&#34; maildir alias &lt;aliases&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">action &#34;relay&#34; relay host smtp+tls://identifiant@serveur:587 auth &lt;secrets&gt; mail-from &#34;@your-domain.tld&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Uncomment the following to accept external mail for domain &#34;example.org&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># match from any for domain &#34;example.org&#34; action &#34;local&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match for local action &#34;local&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match from local for any action &#34;relay&#34;</span>
</span></span></code></pre></div><hr>
<p><strong>Explications</strong></p>
<p>Par rapport à la version originale, nous avons donc rajouté :</p>
<ul>
<li>
<p>la ligne  <code>table secrets</code> qui appelle le fichier <code>.config/mail/secrets</code> -
<em>ou son équivalent, si vous l&rsquo;avez personnalisé</em>…</p>
</li>
<li>
<p>la ligne <code>action relay</code> qui nous permet de définir l&rsquo;action nécessaire
vers l&rsquo;hôte relais par lequel nous enverrons les mails…</p>
<ul>
<li>
<p>REMARQUEZ l&rsquo;écriture  <code>identifiant@serveur</code> :</p>
<ul>
<li>c&rsquo;est justement là qu&rsquo;il faut remplacer la chaîne <code>identifiant</code>
par celle que vous avez créée dans votre fichier <code>secrets</code>.</li>
<li>quant à la chaîne <code>serveur</code>, il faut la remplacer par l&rsquo;adresse
du serveur de mail, par exemple : <code> </code>mail.gandi.net`.</li>
</ul>
</li>
<li>
<p>la chaîne <code>smtp+tls</code> est le protocol que nous utilisons pour nous
connecter au service de l&rsquo;hôte mail relais… <br>
il est bien sûr possible d&rsquo;utiliser les autres protocoles, tel
que :</p>
<ul>
<li>
<p><code>lmtp</code> pour se connecter avec une session 


















































<abbr lang="en" title="Local Mail Transfer Protocol">LMTP</abbr>





























































.</p>
</li>
<li>
<p><code>smtp</code> pour essayer de se connecter avec une session 



























































































<abbr lang="en" title="Start TLS">STARTTLS</abbr>





















si possible</p>
</li>
<li>
<p><code>smtp+tls</code> pour obliger une connexion par le biais d&rsquo;une
session 



























































































<abbr lang="en" title="Start TLS">STARTTLS</abbr>




















.</p>
</li>
<li>
<p><code>smtp+notls</code> pour se connecter &ldquo;en clair&rdquo;, sans chiffrement</p>
</li>
<li>
<p><code>smtps</code> pour se connecter en forçant la connexion

            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            <abbr lang="en" title="Transport Layer Secure">TLS</abbr>
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
</p>
<ul>
<li><em>port par défaut : 465</em>.</li>
</ul>
</li>
<li>
<p>si rien n&rsquo;est spécifié, alors la connexion se fera sur le port
25.</p>
</li>
</ul>
</li>
<li>
<p>la chaîne <code>auth</code> permet de spécifier la table <code>secrets</code> fournissant
les données d&rsquo;identification  mail nécessaires.</p>
</li>
<li>
<p>la chaîne <code>mail-from</code> nous permet de spécifier le nom de domaine -
ce qui permet d&rsquo;éviter l&rsquo;erreur
<code>Sender address rejected: Domain not found</code> ; <br>
<em>il faut bien sûr que ce domaine vous appartienne…</em></p>
</li>
<li>
<p>la ligne <code>match … action &quot;relay&quot;</code> est l&rsquo;action qui sera déclenchée
lors de l&rsquo;envoi de mails à l&rsquo;extérieur !</p>
</li>
</ul>
</li>
</ul>
<h3 id="gestion-des-alias">Gestion des alias</h3>
<p>Un mot sur la gestion des alias système !</p>
<p>Il est intéressant de gérer l&rsquo;alias relatif à votre compte <code>root</code> voire celui
de votre utilisateur principal…</p>
<p>Éditez le fichier <code>/etc/aliases</code>, avec des droits administrateurs. <br>
Vers la fin du fichier, modifiez <code>root</code> en lui indiquant vers quelle adresse
mail vous désirez que les messages systèmes adressés au compte root vous soit
envoyés !</p>
<p>Faites de même pour votre utilisateur système ;)</p>
<p>N&rsquo;oubliez pas de recharger la base des aliases, grâce à l&rsquo;usage de la
commande <code>newaliases</code> !</p>
<h2 id="utilisation">Utilisation</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Avant de redémarrer le service <strong>opensmtpd</strong> pour qu&rsquo;il prenne en compte les
modifications faites, il nous faut tester l&rsquo;écriture de la configuration : <br>
<code>:# smtpd -n</code></p>
<p>qui devrait réponde par : <code>configuration OK</code> <br>
informant ainsi que tout va bien…</p>
<p>Sinon, rééditez le fichier de configuration à la ligne indiquée en premier ;
c&rsquo;est d&rsquo;elle que vient l&rsquo;erreur principale !</p>
</div>

<p>Il est nécessaire de redémarrer le service : <br>
<code># service opensmtpd restart</code>, ou <br>
<code># /etc/init.d/opensmtpd restart</code> - <br>
si vous utilisez <strong>openrc</strong> en tant que gestionnaire de service !</p>
<h3 id="envois">Envois</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">L&rsquo;outil <strong>mail</strong> fait partie du paquet <strong>mailutils</strong> !</div>

<p>Soit :</p>
<ul>
<li><code>echo &quot;Test d'envois de mail on $(hostname); date: $(date)&quot; | mail -s &quot;Test de mail&quot; adresse_mail_à_qui_envoyer</code></li>
<li>ou, <code>echo &quot;Test d'envois de mail on $(hostname); date: $(date)&quot; | mail -s &quot;Test de mail&quot; root</code></li>
</ul>
<p>Dans un cas, comme dans l&rsquo;autre, le journal vous indiquera
l&rsquo;équivalent, en cas de réussite, d&rsquo;un tel message :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">(…)
Apr 27 09:16:47 pc-z smtpd[1718]: 09cca279ca1178e4 smtp connected address=local host=***
Apr 27 09:16:47 pc-z smtpd[1718]: 09cca279ca1178e4 smtp message msgid=85868a25 size=474 nrcpt=1 proto=ESMTP
Apr 27 09:16:47 pc-z smtpd[1718]: 09cca279ca1178e4 smtp envelope evpid=85868a25fcb1569a from=&lt;my-id@***&gt; to=&lt;my-id@***&gt;
Apr 27 09:16:47 pc-z smtpd[1718]: 09cca279ca1178e4 smtp disconnected reason=quit
Apr 27 09:16:51 pc-z smtpd[1718]: 09cca27892fa38ea mta delivery evpid=85868a25fcb1569a from=&lt;my-id@huc.fr.eu.org&gt; to=&lt;email@nom-de-domaine.tld&gt; rcpt=&lt;my-id@***&gt; source=&#34;192.168.47.47&#34; relay=&#34;80.67.160.70 (lautre.net)&#34; delay=4s result=&#34;Ok&#34; stat=&#34;250 2.0.0 Ok: queued as 53C92112839&#34;
Apr 27 09:17:02 pc-z smtpd[1718]: 09cca27892fa38ea mta disconnected reason=quit messages=2
(…)
</code></pre><p>À partir de maintenant, vous pourrez envoyer depuis votre console ou vos
scripts shell des mails avec authentification SMTP !</p>
<h3 id="erreurs">Erreurs</h3>
<p>Retrouvez les différentes erreurs possibles sur mon article
<a class="inside" href="/fr/sys/openbsd/smtpd-config-auth/#gestion-des-erreurs" title="Lien interne vers l&#39;article : 'OpenBSD : Configurer smtpd.conf pour l&#39;authentification (depuis OpenBSD ≥ 6.4)'">OpenBSD : Configurer smtpd.conf pour l&#39;authentification (depuis OpenBSD ≥ 6.4)</a></p>
<h2 id="documentations">Documentations</h2>
<p>Le protocol SMTP est défini par la RFC 5321 :</p>

<h3 id="rfc-5321">RFC 5321</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc5321" title="RFC 5321 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc5321" title="RFC 5321 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc5321.txt" title="RFC 5321 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc5321.html" title="RFC 5321 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc5321.txt.pdf" title="RFC 5321 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc5321.txt" title="RFC 5321 : au format Text">TXT</a>
	</dd>
</dl>

<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/smtpd.conf.5" title="Page du Manuel OpenBSD pour : smtpd.conf">smtpd.conf(5)</a>
</li>
</ul>
<h3 id="wikipédia">Wikipédia</h3>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Local_Mail_Transfer_Protocol" title="Article Wikipédia : Local_Mail_Transfer_Protocol">Local_Mail_Transfer_Protocol <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer OpenSMTPD sous Devuan et le configurer en tant que client avec authentification]]></summary>
        <published>2020-04-27T09:19:56+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c5153753-5dfb-2c3e-3bf4-3362cb51ed07</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/devuan/openntpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Devuan : utiliser le client de synchronisation de temps OpenNTPD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Devuan" scheme="http://doc.huc.fr.eu.org/fr/tags/devuan/" />
        <category term="OpenNTPD" scheme="http://doc.huc.fr.eu.org/fr/tags/openntpd/" />
        <category term="ntp" scheme="http://doc.huc.fr.eu.org/fr/tags/ntp/" />
        <category term="client" scheme="http://doc.huc.fr.eu.org/fr/tags/client/" />
        <category term="temps" scheme="http://doc.huc.fr.eu.org/fr/tags/temps/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenNTPD</strong> est un service qui peut être utilisé pour synchroniser l&rsquo;horloge
système depuis les serveurs de temps, utilisant le protocole 


































































<span lang="en">NTP <em>(Network Time Protocol)</em></span>












































.</p>
<p><strong>OpenNTPD</strong> fait partie du système de base du système d&rsquo;exploitation OpenBSD.
Il a été &ldquo;porté&rdquo; sur d&rsquo;autres OS, tel Devuan.</p>
<h2 id="installation">Installation</h2>
<p>Par le biais de l&rsquo;outil <code>apt</code> : <code>apt install openntpd</code></p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration se trouve être dans : <code>/etc/opennptd/ntpd.conf</code></li>
</ul>
<p>Par défaut, il est paramétré pour fonctionner, sans aucune modification nécessaire.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: ntpd.conf,v 1.14 2015/07/15 20:28:37 ajacoutot Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sample ntpd configuration file, see ntpd.conf(5)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Addresses to listen on (ntpd does not listen by default)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#listen on *</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#listen on 127.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#listen on ::1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sync to a single server</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#server ntp.example.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a random selection of NTP Pool Time Servers</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># see http://support.ntp.org/bin/view/Servers/NTPPoolServers</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#servers pool.ntp.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Choose servers announced from Debian NTP Pool</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers 0.debian.pool.ntp.org</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers 1.debian.pool.ntp.org</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers 2.debian.pool.ntp.org</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers 3.debian.pool.ntp.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a specific local timedelta sensor (radio clock, etc)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sensor nmea0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use all detected timedelta sensors</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sensor *</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<p>À-propos des options :</p>
<ul>
<li><code>server</code> permet de cibler un serveur de temps, en particulier</li>
<li><code>servers</code> permet de cibler un ensemble de serveur de temps - <em>préférez cet usage</em></li>
<li><code>sensor</code> permet d&rsquo;utiliser les sondes de temps locales</li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<h3 id="contrôles">Contrôles</h3>
<p>Pour vérifier que la configuration soit bonne, il faut utiliser l&rsquo;option
<code>-n</code> tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># openntpd -n</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">`</span>configuration OK
</span></span></code></pre></div><p>Si la configuration du fichier n&rsquo;est pas bonne, la commande vous avertira
en conséquence ; à vous, de corriger le fichier de configuration si nécessaire.</p>
<hr>
<p>L&rsquo;utilitaire qui nous permet de contrôler le service de temps est <code>ntpctl</code>.</p>
<ul>
<li>L&rsquo;option <code>-s all</code> - <em>ou sa version abrégée</em> : <code>-sa</code> - permet d&rsquo;afficher
les informations disponibles.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># ntpctl -sa</span>
</span></span><span style="display:flex;"><span>4/4 peers valid, clock unsynced, clock offset is -552.476ms
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>peer
</span></span><span style="display:flex;"><span>   wt tl st  next  poll          offset       delay      jitter
</span></span><span style="display:flex;"><span>82.64.42.185 from pool 0.debian.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span> <span style="color:#f99b15">10</span>  <span style="color:#f99b15">2</span>    6s   32s         0.203ms    60.784ms    31.533ms
</span></span><span style="display:flex;"><span>194.177.34.116 from pool 0.debian.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span> <span style="color:#f99b15">10</span>  <span style="color:#f99b15">3</span>    9s   32s         2.000ms    54.595ms    17.411ms
</span></span><span style="display:flex;"><span>212.129.10.70 from pool 0.debian.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span> <span style="color:#f99b15">10</span>  <span style="color:#f99b15">2</span>    9s   33s         5.552ms    51.518ms     4.078ms
</span></span><span style="display:flex;"><span>162.159.200.1 from pool 0.debian.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span> <span style="color:#f99b15">10</span>  <span style="color:#f99b15">3</span>    7s   33s        -0.176ms    55.383ms    17.593ms
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pour connaître les différents options utiles, je vous renvoie au
manpage <a href="/fr/sys/devuan/openntpd/#manpages">ntpctl</a> correspondant.</div>

<h3 id="service">Service</h3>
<p>Le nom du service étant <strong>openntpd</strong>, il se gère avec l&rsquo;outil <code>service</code>,
sans soucis particulier.</p>
<p><code>service openntpd commande</code></p>
<ul>
<li><code>commande</code> est bien sûr une des actions possibles sur un service, tel <code>start</code>,
<code>stop</code>, <code>restart</code> par exemple.</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<p>Il peut arriver au démarrage qu&rsquo;il y ait un décalage de temps, plus ou moins
conséquent.</p>
<p>L&rsquo;usage de  l&rsquo;option <code>-s</code> permettra de résoudre :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># openntpd -s -d</span>
</span></span><span style="display:flex;"><span>adjtimex returns frequency of 0.000000ppm
</span></span><span style="display:flex;"><span>/var/lib/openntpd/db/ntpd.drift is empty
</span></span><span style="display:flex;"><span>ntp engine ready
</span></span><span style="display:flex;"><span>reply from 212.83.179.156: offset -522.890034 delay 0.054365, next query 7s
</span></span><span style="display:flex;"><span>set local clock to Sat Apr <span style="color:#f99b15">25</span> 12:09:03 CEST <span style="color:#f99b15">2020</span> <span style="color:#5bc4bf">(</span>offset -522.890034s<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>reply from 5.135.3.88: negative delay -522.825725s, next query 3203s
</span></span><span style="display:flex;"><span>reply from 46.105.237.136: negative delay -522.823915s, next query 3197s
</span></span><span style="display:flex;"><span>reply from 185.21.216.198: negative delay -522.821620s, next query 3012s
</span></span><span style="display:flex;"><span>reply from 51.15.175.180: negative delay -522.821769s, next query 3010s
</span></span><span style="display:flex;"><span>reply from 37.187.104.44: negative delay -522.820949s, next query 3031s
</span></span><span style="display:flex;"><span>reply from 46.235.141.130: negative delay -522.816360s, next query 3274s
</span></span><span style="display:flex;"><span>reply from 162.159.200.1: negative delay -522.816819s, next query 3030s
</span></span><span style="display:flex;"><span>reply from 5.39.60.244: negative delay -522.816297s, next query 3254s
</span></span><span style="display:flex;"><span>reply from 95.81.173.155: negative delay -522.812132s, next query 3176s
</span></span><span style="display:flex;"><span>reply from 51.15.191.239: negative delay -522.810759s, next query 3017s
</span></span><span style="display:flex;"><span>reply from 5.39.60.244: negative delay -522.809750s, next query 3082s
</span></span><span style="display:flex;"><span>reply from 51.158.147.92: negative delay -522.805041s, next query 3250s
</span></span><span style="display:flex;"><span>reply from 212.85.158.10: negative delay -522.800165s, next query 3041s
</span></span><span style="display:flex;"><span>reply from 88.212.196.95: negative delay -522.784156s, next query 3179s
</span></span><span style="display:flex;"><span>reply from 156.38.0.219: negative delay -522.657588s, next query 3023s
</span></span><span style="display:flex;"><span>reply from 212.83.179.156: offset -0.004612 delay 0.049539, next query 7s
</span></span><span style="display:flex;"><span>reply from 212.83.179.156: offset -0.007646 delay 0.049241, next query 9s
</span></span><span style="display:flex;"><span>peer 212.83.179.156 now valid
</span></span></code></pre></div><h3 id="contrainte">Contrainte</h3>
<p>Apparemment l&rsquo;option de contrainte <code>constraints</code> bien appréciée sous OpenBSD
n&rsquo;est pas utilisable !</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">L&rsquo;option de contrainte permet de s&rsquo;assurer que les requêtes de temps se
fassent sur le protocole <abbr title="HyperText Transfert Protocole Secure">HTTPS</abbr>
,
via <abbr title="Transport Layer Security">TLS</abbr>
.</div>

<h3 id="peer-not-valid">peer not valid</h3>
<p>Il peut arriver lorsque vous utilisez le contrôleur ntp, il vous soit notifié
qu&rsquo;un ou plusieurs des pairs soi(en)t non valides, tel que par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>   wt tl st  next  poll          offset       delay      jitter
</span></span><span style="display:flex;"><span>95.81.173.8 from pool 0.debian.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">4</span>  <span style="color:#f99b15">2</span>    8s    9s             ---- peer not valid ----
</span></span></code></pre></div><p>Patientez encore un peu que les retours des requêtes ntp se soient faites. <br>
Normalement lors de l&rsquo;interrogation suivante, cela ne devrait plus être le cas.</p>
<p>Autrement, vérifiez que les serveurs NTP enregistrés dans le fichier de
configuration soient bien écrits, joignables et fonctionnels.</p>
<h2 id="documentation">Documentation</h2>
<p>Le protocol NTP est défini dans la version :</p>
<ul>
<li><strong>3</strong> par la <a href="/fr/sys/devuan/openntpd/#rfc-1305">RFC 1305</a></li>
<li><strong>4</strong> par la <a href="/fr/sys/devuan/openntpd/#rfc-5905">RFC 5905</a></li>
</ul>
<p>
<h3 id="rfc-1305">RFC 1305</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc1305" title="RFC 1305 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc1305" title="RFC 1305 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc1305.txt" title="RFC 1305 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc1305.html" title="RFC 1305 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc1305.txt.pdf" title="RFC 1305 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc1305.txt" title="RFC 1305 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-5905">RFC 5905</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc5905" title="RFC 5905 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc5905" title="RFC 5905 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc5905.txt" title="RFC 5905 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc5905.html" title="RFC 5905 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc5905.txt.pdf" title="RFC 5905 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc5905.txt" title="RFC 5905 : au format Text">TXT</a>
	</dd>
</dl>
</p>
<h3 id="manpages">Manpages</h3>
<p>Du fait que les outils viennent de l&rsquo;univers OpenBSD, je vous renvoie aux
manpages compétents correspondants :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ntpd.8" title="Page du Manuel OpenBSD pour : ntpd">ntpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/ntpd.conf.5" title="Page du Manuel OpenBSD pour : ntpd.conf">ntpd.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/ntpctl.8" title="Page du Manuel OpenBSD pour : ntpctl">ntpctl(8)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser sous Devuan le client de synchronisation de temps OpenNTPD]]></summary>
        <published>2020-04-25T12:17:36+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:14169976-e569-3497-1dc2-dce14c6c83d3</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-opensearch/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Opensearch</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="Opensearch" scheme="http://doc.huc.fr.eu.org/fr/tags/opensearch/" />
        <category term="search" scheme="http://doc.huc.fr.eu.org/fr/tags/search/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Opensearch</strong> est un format de description qui permet à un site de décrire
un moteur de recherche pour lui-même, afin que toute application cliente,
tel un navigateur web, puisse faire une recherche dans le site en question.</p>
<p>La plupart des navigateurs vous proposeront l&rsquo;ajout de votre site en tant
que moteur de recherche si vous gérez l&rsquo;<a href="/fr/web/hugo/hugo-opensearch/#autopublication">autopublication</a>.</p>
<p><strong>Hugo</strong>, par défaut, ne génére pas de descriptif Opensearch. Nous allons
devoir modifier la <a href="/fr/web/hugo/hugo-opensearch/#configuration">configuration</a> pour créer un nouveau format
de sortie personnalisé.</p>
<h2 id="documentation">Documentation</h2>
<p>Un petit tour sur la documentation officielle Hugo :</p>
<ul>
<li><a href="https://gohugo.io/templates/output-formats/" title="Lien vers la page du site officiel Hugo : Templates &gt; Output formats">Hugo Documentation : Templates &gt; Output formats</a>
</li>
</ul>
<p>Ainsi que sur la documentation officielle d&rsquo;Opensearch :</p>
<ul>
<li><a href="https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md" rel="external">https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md</a></li>
</ul>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration principal : <code>config.toml</code></li>
</ul>
<p>Il est nécessaire de modifier le fichier de configuration pour :</p>
<ul>
<li>créer un nouveau <a href="/fr/web/hugo/hugo-opensearch/#mediatype">type de média</a></li>
<li>créer un nouveau <a href="/fr/web/hugo/hugo-opensearch/#ouputformat">format de sortie</a></li>
<li>créer le <a href="/fr/web/hugo/hugo-opensearch/#template">modèle</a> pour le fichier Opensearch.</li>
</ul>
<h3 id="mediatype">MediaType</h3>
<p>Le type mime lié au format de description d&rsquo;Opensearch est : <code>application/opensearchdescription+xml</code>.</p>
<h4 id="hugo--020">Hugo &gt;= 0.20</h4>
<p>Depuis Hugo 0.20, il faut ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffix</span> = <span style="color:#48b685">&#34;xml&#34;</span>
</span></span></code></pre></div><p>Là, nous avons donc implémenté un nouveau type de format ayant pour mime type : <code>application/opensearchdescription+xml</code>, et pour nom d&rsquo;extension : <code>xml</code>.</p>
<h4 id="hugo--044">Hugo &gt;= 0.44</h4>
<p>Depuis Hugo 0.44, pour que cela fonctionne correctement il faut ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffixes</span> = [<span style="color:#48b685">&#34;xml&#34;</span>]
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si votre ancienne configuration précédait la 0.44, il faut adapter/transformer
la variable <code>suffix</code> en <code>suffixes = ['xml']</code> !</div>

<h3 id="ouputformat">OuputFormat</h3>
<p>La déclaration du format de sortie, à ajouter  :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">OpenSearch</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;opensearch&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isHTML</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">noUgly</span> = <span style="color:#815ba4">true</span>
</span></span></code></pre></div><p>Puis, il faut ajouter <code>&quot;OpenSearch&quot;</code> à votre variable <code>home</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;OpenSearch&#34;</span>]
</span></span></code></pre></div><h3 id="template">Template</h3>
<p>Le modèle peut simplement être créé dans le répertoire <code>layouts/_default/index.opensearch.xml</code>.</p>
<ul>
<li>Si le site est multilangue, les liens alternatifs vers la version de langue
correspondante à l&rsquo;entrée du site sont générés.</li>
</ul>
<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">ATTENTION : le modèle présenté gère un site multilingue. <br>
Tenez-en compte, en supprimant les déclarations de langue, si ce n&rsquo;est pas
votre cas.</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>{{ printf `<span style="color:#776e71">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&gt;</span>` | safeHTML }}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;OpenSearchDescription</span> <span style="color:#06b6ef">xmlns=</span><span style="color:#48b685">&#34;http://a9.com/-/spec/opensearch/1.1/&#34;</span> <span style="color:#06b6ef">xmlns:ie=</span><span style="color:#48b685">&#34;http://schemas.microsoft.com/Search/2008/&#34;</span> <span style="color:#06b6ef">xmlns:moz=</span><span style="color:#48b685">&#34;http://www.mozilla.org/2006/browser/search/&#34;</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Attribution&gt;</span>© {{ $.Date.Format &#34;2006&#34; | safeHTML }} {{ site.Author.name }}; http://creativecommons.org/publicdomain/zero/1.0/legalcode.{{ site.Language.Lang }}<span style="color:#5bc4bf">&lt;/Attribution&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Contact&gt;</span>{{ site.Author.email | safeHTML }}<span style="color:#5bc4bf">&lt;/Contact&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Description&gt;</span>{{ i18n &#34;opensearchDescription&#34; }}<span style="color:#5bc4bf">&lt;/Description&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Developer&gt;</span>{{ site.Author.name | safeHTML }}<span style="color:#5bc4bf">&lt;/Developer&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;InputEncoding&gt;</span>utf-8<span style="color:#5bc4bf">&lt;/InputEncoding&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Image</span> <span style="color:#06b6ef">width=</span><span style="color:#48b685">&#34;64&#34;</span> <span style="color:#06b6ef">height=</span><span style="color:#48b685">&#34;64&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;image/png&#34;</span><span style="color:#5bc4bf">&gt;</span>{{ site.BaseURL }}img/Logo-64px.png<span style="color:#5bc4bf">&lt;/Image&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Image</span> <span style="color:#06b6ef">width=</span><span style="color:#48b685">&#34;16&#34;</span> <span style="color:#06b6ef">height=</span><span style="color:#48b685">&#34;16&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;image/vnd.microsoft.icon&#34;</span><span style="color:#5bc4bf">&gt;</span>{{ site.BaseURL }}img/favicon.ico<span style="color:#5bc4bf">&lt;/Image&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Language&gt;</span>{{ site.LanguageCode }}<span style="color:#5bc4bf">&lt;/Language&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;LongName&gt;</span>{{ site.Title }} :: {{ site.Language.Lang }}<span style="color:#5bc4bf">&lt;/LongName&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;OutputEncoding&gt;</span>UTF-8<span style="color:#5bc4bf">&lt;/OutputEncoding&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;ShortName&gt;</span>Websearch<span style="color:#5bc4bf">&lt;/ShortName&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;SyndicationRight&gt;</span>open<span style="color:#5bc4bf">&lt;/SyndicationRight&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;ie:PreviewUrl</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;text/html&#34;</span> <span style="color:#06b6ef">method=</span><span style="color:#48b685">&#34;GET&#34;</span> <span style="color:#06b6ef">template=</span><span style="color:#48b685">&#34;{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/&#34;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;moz:SearchForm&gt;</span>{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/<span style="color:#5bc4bf">&lt;/moz:SearchForm&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Url</span> <span style="color:#06b6ef">template=</span><span style="color:#48b685">&#34;{{ site.BaseURL }}{{ site.Language.Lang }}/tags/{searchTerms}/&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;text/html&#34;</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;Url</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;self&#34;</span> <span style="color:#06b6ef">template=</span><span style="color:#48b685">&#34;{{ site.BaseURL }}opensearch.xml&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;/OpenSearchDescription&gt;</span>
</span></span></code></pre></div><h2 id="autopublication">autopublication</h2>
<p>L&rsquo;autopublication est la méthode qui permet d&rsquo;informer les clients web du
format de description Opensearch.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Veillez à ce que la valeur de l&rsquo;attribut <code>title</code> corresponde à celle de
l&rsquo;élément <code>ShortName</code> !</div>

<h3 id="atom">Atom</h3>
<p>Si vous avez modifié votre configuration de Hugo pour générer un flux
<a class="inside" href="/fr/web/hugo/hugo-feed/#atom" title="Lien interne vers l&#39;article : 'Hugo : Feed Atom, JSON, RSS'">Atom</a>

il vous faudra le modifier pour ajouter ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">link</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ site.BaseURL }}/opensearch.xml&#34;</span> <span style="color:#06b6ef">rel</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Websearch&#34;</span> /&gt;
</span></span></code></pre></div><h3 id="html">HTML</h3>
<p>Ajouter un élément <code>link</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">link</span> <span style="color:#06b6ef">rel</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/opensearch.xml&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Websearch&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span>&gt;
</span></span></code></pre></div><h3 id="rss">RSS</h3>
<p>Si vous générez votre flux <a class="inside" href="/fr/web/hugo/hugo-feed/#rss" title="Lien interne vers l&#39;article : 'Hugo : Feed Atom, JSON, RSS'">RSS</a>
,
veillez à le modifier pour ajouter :</p>
<ul>
<li>la déclaration de l&rsquo;attribut <code>xmlns:atom=&quot;http://www.w3.org/2005/Atom&quot;</code>
dans votre élément <code>rss</code>, tel que :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">rss</span> <span style="color:#06b6ef">version</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;2.0&#34;</span> <span style="color:#06b6ef">xmlns:atom</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;http://www.w3.org/2005/Atom&#34;</span>&gt;
</span></span></code></pre></div><ul>
<li>afin de pouvoir déclarer un élément <code>atom:link</code>, tel que :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">atom:link</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ site.BaseURL }}/opensearch.xml&#34;</span> <span style="color:#06b6ef">rel</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;application/opensearchdescription+xml&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Websearch&#34;</span> /&gt;
</span></span></code></pre></div><hr>
<h2 id="remerciements">Remerciements</h2>
<p>Encore un merci sincère @<a href="https://dataswamp.org/~solene/" rel="external">solene</a> qui m&rsquo;a fait
connaître Opensearch.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place le format de description Opensearch dans Hugo !]]></summary>
        <published>2020-04-14T16:54:07+02:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9370ce52-5591-c5b9-3dc5-f67e14de90bf</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/fswebcam/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: fswebcam / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="fswebcam" scheme="http://doc.huc.fr.eu.org/fr/tags/fswebcam/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>fswebcam</strong> est une une petite application simple de gestion de webcam.
Elle peut capturer des images depuis différentes sources et effectuer
des manipulations simples sur les images capturées. Les images peuvent
être sauvegardées au format JPG ou PNG.</p>
<ul>
<li>Site officiel : <a href="http://www.sanslogic.co.uk/fswebcam/" rel="external">http://www.sanslogic.co.uk/fswebcam/</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>fswebcam</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="configuration-système">Configuration Système</h3>
<p>Il est nécessaire de capturer le périphérique vidéo !
[[tips:webcam|capturer le périphérique vidéo]]</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si votre webcam a une entrée micro, il peut être possible de paramétrer
l&rsquo;audio en tenant compte de cette [[tips:audio-son#enregistrement-audio|information]]…</div>

<h2 id="utilisation">Utilisation</h2>
<p>Voici un exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ fswebcam -r 1280x960 --save <span style="color:#48b685">&#34;/tmp/webcam-</span><span style="color:#815ba4">$(</span>date +%Y-%m-%d-%H-%M-%S<span style="color:#815ba4">)</span><span style="color:#48b685">.jpg&#34;</span>
</span></span><span style="display:flex;"><span>--- Opening /dev/video0...
</span></span><span style="display:flex;"><span>Trying source module v4l2...
</span></span><span style="display:flex;"><span>/dev/video0 opened.
</span></span><span style="display:flex;"><span>No input was specified, using the first.
</span></span><span style="display:flex;"><span>Adjusting resolution from 1280x960 to 960x720.
</span></span><span style="display:flex;"><span>--- Capturing frame...
</span></span><span style="display:flex;"><span>Captured frame in 0.00 seconds.
</span></span><span style="display:flex;"><span>--- Processing captured image...
</span></span><span style="display:flex;"><span>Writing JPEG image to <span style="color:#48b685">&#39;/tmp/webcam-2020-03-18-13-24-42.jpg
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;</span>.
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[fswebcam, une application simple et légère de gestion de webcam sous OpenBSD]]></summary>
        <published>2020-03-18T15:34:01+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4de21288-5284-eb81-0afe-8b2601defb70</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/switch-lan-wan/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT: Switch LAN WAN (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="switch" scheme="http://doc.huc.fr.eu.org/fr/tags/switch/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par défaut, <strong>WAN</strong> est sur le port <strong>0</strong> et <strong>LAN</strong> accessible sur les autres
ports, le port <strong>1</strong> étant celui par défaut. Ce qui signifie matériellement que
votre câble Ethernet qui vient de votre FAIbox est connecté sur le port 0, et
celui qui va vers votre réseau Lan est connecté sur le port 1.</p>
<p>Il peut être intéressant de faire en sorte que sur votre routeur :</p>
<ul>
<li>le port par défaut dédié à <strong>LAN</strong> soit le port <strong>0</strong></li>
<li>le port dédié à <strong>WAN</strong> soit le dernier port disponible.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Je prend pour contexte celui du routeur
<a class="inside" href="/fr/sys/openwrt/ubiquiti-edgerouteur-x/" title="Lien interne vers l&#39;article : ''">Ubiquity EdgeRouter X</a>
. <br>
Adaptez à votre routeur… :p</div>

<h2 id="configuration">Configuration</h2>
<h3 id="luci">LuCI</h3>
<p>Si l&rsquo;interface d&rsquo;administration <strong>LuCI</strong> est installée, allez dans le menu
&lsquo;System&rsquo; &gt; &lsquo;Switch&rsquo;.</p>
<ul>
<li>Concernant le premier VLAN : mettre <strong>LAN4</strong> sur <code>off</code></li>
<li>sur le deuxième VLAN : positionner <strong>LAN4</strong> sur <code>untagged</code>.</li>
</ul>
<h3 id="réseau">Réseau</h3>
<p>Le fichier de configuration aura cette aspect :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash">$ cat /etc/config/network
(…)
config switch_vlan
    option device &#39;switch0&#39;
    option vlan &#39;1&#39;
    option ports &#39;0 1 2 3 6t&#39;

config switch_vlan
    option device &#39;switch0&#39;
    option vlan &#39;2&#39;
    option ports &#39;4 6t&#39;
(…)
</code></pre><h2 id="services">Services</h2>
<p>Il faudra redémarrer le service <code>network</code> et recharger le service <code>firewall</code>.</p>
<p><code># /etc/init.d/network restart</code> <br>
<code># /etc/init.d/firewall reload</code></p>
<p>Puis connecter les cables Ethernet pour :</p>
<ul>
<li>le réseau LAN sur le port 0</li>
<li>vers votre FAIBox, sur le port 4.</li>
</ul>
<p>Et, voilà !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[OpenWRT : comment basculer les interfaces LAN et WAN pour un résultat physique plus logique. LAN : port 0 ; WAN : dernier port !]]></summary>
        <published>2020-02-29T20:03:21+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a15243ac-c81c-540e-155f-ada67aeb977f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/ubiquiti-edgerouter-x/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Ubiquiti EdgeRouter X</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="Ubiquiti" scheme="http://doc.huc.fr.eu.org/fr/tags/ubiquiti/" />
        <category term="routeur" scheme="http://doc.huc.fr.eu.org/fr/tags/routeur/" />
        <category term="EdgeRouter" scheme="http://doc.huc.fr.eu.org/fr/tags/edgerouter/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Le routeur <strong><a href="https://www.ui.com/edgemax/edgerouter-x/" rel="external">EdgeRouter X</a></strong> fait partie de la gamme <strong>EdgeMax</strong> des produits
fabriqués par la société <strong><a href="https://www.ui.com" rel="external">Ubiquiti</a></strong>. C&rsquo;est un routeur 5 ports Gigabits,
sans Wifi.</p>
<p>Cet article a pour propos de montrer l&rsquo;installation d&rsquo;OpenWRT sur ce petit routeur.</p>
<ul>
<li>OpenWRT : v19.07.1</li>
</ul>
<h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://openwrt.org/toh/ubiquiti/edgerouter_x_er-x_ka" rel="external">https://openwrt.org/toh/ubiquiti/edgerouter_x_er-x_ka</a></li>
<li><a href="https://forum.openwrt.org/t/ubiquiti-edgerouter-x-loading-openwrt-and-performance-numbers/27470" rel="external">https://forum.openwrt.org/t/ubiquiti-edgerouter-x-loading-openwrt-and-performance-numbers/27470</a></li>
<li><a href="https://openwrt.org/docs/guide-user/services/webserver/http.uhttpd" rel="external">https://openwrt.org/docs/guide-user/services/webserver/http.uhttpd</a></li>
</ul>
<h3 id="documentations-tierces">Documentations tierces</h3>
<ul>
<li>En apprendre un peu plus sur 
<a class="inside" href="/fr/sys/openwrt/about/" title="Lien interne vers l&#39;article : 'OpenWRT : Présentation du projet'">OpenWRT</a>
</li>
<li><a href="https://www.ui.com/download/edgemax/edgerouter-x" rel="external">Ubiquiti :: firmware officiel</a></li>
<li><a href="https://fr.wikipedia.org/wiki/R%c3%a9seau_local_virtuel" title="Article Wikipédia : Réseau_local_virtuel">Réseau_local_virtuel <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Actuellement, l&rsquo;installation du firmware peut se faire depuis une console SSH. <br>
<em>(si vous souhaitez la faire par TFTP, lisez cet <a href="http://sector5d.org/openwrt-on-the-ubiquiti-edgerouter-x.html" rel="external">article</a> - en anglais -)</em></p>
<h3 id="recommandations">Recommandations</h3>
<p>Par défaut le routeur est fourni avec EdgeOS ; le compte est <strong>ubnt</strong>.</p>
<p>Veillez à :</p>
<ul>
<li>vous connecter sur le port 1 ;</li>
<li>avoir une adresse IP dans le segment réseau privé de classe C, à savoir 192.168.1.x.
En effet, le routeur a pour défaut l&rsquo;adresse IP*(v4)* : 192.168.1.1.</li>
</ul>
<h3 id="faux-départ">Faux départ</h3>
<p>En premier lieu, téléchargeons le firmware :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ftp http://downloads.openwrt.org/releases/19.07.1/targets/ramips/mt7621/openwrt-19.07.1-ramips-mt7621-ubnt-erx-initramfs-kernel.bin
</span></span><span style="display:flex;"><span>Trying 2a01:4f8:150:6449::2...
</span></span><span style="display:flex;"><span>Requesting http://downloads.openwrt.org/releases/19.07.1/targets/ramips/mt7621/openwrt-19.07.1-ramips-mt7621-ubnt-erx-initramfs-kernel.bin
</span></span><span style="display:flex;"><span>100% |************************************************************************************************************************************************************************************************************|  <span style="color:#f99b15">3461</span> KB    00:04
</span></span><span style="display:flex;"><span><span style="color:#f99b15">3545054</span> bytes received in 4.55 seconds <span style="color:#5bc4bf">(</span>761.55 KB/s<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Et, envoie sur le routeur en SSH : <br>
<code>:$ scp openwrt-19.07.1-ramips-mt7621-ubnt-erx-initramfs-kernel.bin ubnt@192.168.1.1:/tmp</code></p>
<p>puis on se connecte en SSH au routeur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ssh ubnt@192.168.1.1
</span></span><span style="display:flex;"><span>ubnt@ubnt:/$ cd tmp
</span></span><span style="display:flex;"><span>ubnt@ubnt:/tmp$ add system image openwrt-19.07.1-ramips-mt7621-ubnt-erx-initramfs-kernel.bin
</span></span><span style="display:flex;"><span>Checking upgrade image...Upgrade image does not support the device. Upgrade failed.
</span></span><span style="display:flex;"><span>/tmp
</span></span><span style="display:flex;"><span>:$
</span></span></code></pre></div><p>C&rsquo;est (mal?)heureusement un <a href="https://forum.openwrt.org/t/ubiquiti-edgerouter-x-unable-to-create-initramfs-factory-tar/39739/4" rel="external">problème connu</a> et identifié sur le forum d&rsquo;OpenWRT.
L&rsquo;explication étant que le noyau fourni est trop gros.</p>
<p>Il nous faut télécharger la version fournie par cet autre <a href="https://wiki.opennet-initiative.de/wiki/Ubiquiti_EdgeRouter" rel="external">initiative</a>.</p>
<h3 id="téléchargement">Téléchargement</h3>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il est possible de faire directement le téléchargement du firmware
depuis le routeur après s&rsquo;être déplacé dans le répertoire <code>/tmp</code>.</div>

<p>Téléchargeons le premier firmware :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ftp https://downloads.opennet-initiative.de/ubnt/edgeos/openwrt-ramips-mt7621-ubnt-erx-initramfs-factory.tar
</span></span><span style="display:flex;"><span>Trying 2001:638:804:2228:216:3eff:fe76:4703...
</span></span><span style="display:flex;"><span>Requesting https://downloads.opennet-initiative.de/ubnt/edgeos/openwrt-ramips-mt7621-ubnt-erx-initramfs-factory.tar
</span></span><span style="display:flex;"><span>100% |************************************************************************************************************************************************************************************************************|  <span style="color:#f99b15">2890</span> KB    00:03
</span></span><span style="display:flex;"><span><span style="color:#f99b15">2959360</span> bytes received in 3.85 seconds <span style="color:#5bc4bf">(</span>749.99 KB/s<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>On l&rsquo;envoie sur le routeur en SSH, puis on s&rsquo;y connecte pour l&rsquo;installer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ scp openwrt-ramips-mt7621-ubnt-erx-initramfs-factory.tar ubnt@192.168.1.1:/tmp
</span></span><span style="display:flex;"><span>ubnt@ubnt:/$ cd tmp
</span></span><span style="display:flex;"><span>ubnt@ubnt:/tmp$ add system image openwrt-ramips-mt7621-ubnt-erx-initramfs-factory.tar
</span></span><span style="display:flex;"><span>   Checking upgrade image...Done
</span></span><span style="display:flex;"><span>   Preparing to upgrade...Done
</span></span><span style="display:flex;"><span>   Copying upgrade image.../usr/bin/ubnt-upgrade: line 569: <span style="color:#5bc4bf">[</span>: too many arguments
</span></span><span style="display:flex;"><span>   Done
</span></span><span style="display:flex;"><span>   Removing old image...Done
</span></span><span style="display:flex;"><span>   Checking upgrade image...Done
</span></span><span style="display:flex;"><span>   Copying config data...Done
</span></span><span style="display:flex;"><span>   Finishing upgrade...Done
</span></span><span style="display:flex;"><span>   Upgrade completed
</span></span><span style="display:flex;"><span>show system image
</span></span><span style="display:flex;"><span>   The system currently has the following image<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> installed:
</span></span><span style="display:flex;"><span>   …                 <span style="color:#5bc4bf">(</span>default boot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   v1.9.7+hotfix.3.5013617.170830.0227 <span style="color:#5bc4bf">(</span>running image<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#A reboot is needed to boot default image, which is now are custom OpenWRT</span>
</span></span></code></pre></div><p>Il est maintenant nécessaire de redémarrer le routeur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# reboot
</span></span><span style="display:flex;"><span>   Proceed with reboot? <span style="color:#5bc4bf">[</span>confirm<span style="color:#5bc4bf">]</span>y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#Reboot time was rather fast.  Less then 1m.</span>
</span></span></code></pre></div><p>Une minute plus tard, il est normalement possible de se connecter en SSH au routeur,
mais cette fois-ci avec l&rsquo;identifiant <strong>root</strong>.</p>
<p>Dans l&rsquo;état, la version du firmware est minimaliste, sans aucune
<a class="inside" href="/fr/sys/openwrt/about/#install-luci" title="Lien interne vers l&#39;article : 'OpenWRT : Présentation du projet'">interface d'administration web</a>
.
Il faut <a class="inside" href="/fr/sys/openwrt/about/#description" title="Lien interne vers l&#39;article : 'OpenWRT : Présentation du projet'">connaître les méandres du système</a>

et tout configurer à la main - <br>
<em>ce qui peut devenir très vite délicat et dangereux</em>.</p>
<ul>
<li>Le port 0 du routeur est le port dédié au traffic 













































































































<span lang="en">WAN <em>(World Area Network)</em></span>

, et les
autres, à minima au traffic 















































<span lang="en">LAN <em>(Local Area Network)</em></span>































































.</li>
</ul>
<p>En suite, il est préférable d&rsquo;installer l&rsquo;<a href="http://downloads.openwrt.org/releases/19.07.0/targets/ramips/mt7621/openwrt-19.07.0-ramips-mt7621-ubnt-erx-squashfs-sysupgrade.tar" rel="external">image plus complète du firmware OpenWRT</a> -
et de répéter le <a href="/fr/sys/openwrt/ubiquiti-edgerouter-x/#téléchargement">processus d&rsquo;installation</a>, cela
vous permettra entres autres d&rsquo;avoir l&rsquo;interface web d&rsquo;administration <strong>LuCI</strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Peut-être apprécierez-vous de savoir comment :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/openwrt/ssh/" title="Lien interne vers l&#39;article : ''">sécuriser l&#39;accès web par SSH</a>
</li>
<li>
<a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">créer un nouvel utilisateur pour avoir un accès sécurisé</a>
</li>
</ul>
<p>Peut-être apprécierez-vous l&rsquo;astuce suivante :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/openwrt/opkg-upgrade/" title="Lien interne vers l&#39;article : 'OpenWRT : opkg upgrade (astuce)'">OpenWRT : opkg upgrade (astuce)</a>

</li>
<li>
<a class="inside" href="/fr/sys/openwrt/switch-lan-wan/" title="Lien interne vers l&#39;article : 'OpenWRT: Switch LAN WAN (astuce)'">OpenWRT: Switch LAN WAN (astuce)</a>

</li>
</ul>
<p>Pour le mettre à jour correctement, ça se passe là :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/openwrt/sysupgrade/" title="Lien interne vers l&#39;article : 'OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)'">OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)</a>

</li>
</ul>
<h2 id="notes">Notes</h2>
<h3 id="parefeu">Parefeu</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Dans la section <strong>Routing/NAT Offloading</strong>, depuis la version 19.07.x, bien que
la fonction expérimentale &lsquo;Software flow offloading&rsquo; ne pose pas problème, la
fonctionnalité expérimentale &lsquo;Hardware flow offloading&rsquo; ne fonctionne plus
correctement - ce qui a pour conséquence de bloquer tout traffic. <br>
Celle-ci semble à nouveau fonctionner depuis la version 19.07.7, sinon
basculer vers l&rsquo;ancienne version 18.06 !</div>

<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installation et configuration d&#39;OpenWRT sur un routeur Ubiquiti EdgeMax EdgeRouter X, par connexion SSH.]]></summary>
        <published>2020-02-29T14:15:12+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e2200d6c-635f-4b15-3422-2499de39af3a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/ssh-tunnel/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Tunnel SSH pour LuCI</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="tunnel" scheme="http://doc.huc.fr.eu.org/fr/tags/tunnel/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Abordons l&rsquo;aspect de connexion 
























































































<span lang="en">SSH <em>(Secure SHell)</em></span>






















 dans OpenWRT
pour sécuriser l&rsquo;accès à l&rsquo;interface d&rsquo;administration <strong>LuCI</strong>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Merci de vous référez à mon article <a class="inside" href="/fr/sys/openwrt/about/#ssh" title="Lien interne vers l&#39;article : 'OpenWRT : Présentation du projet'">à-propos d&rsquo;OpenWRT</a></p>
<p>qui restitue quelques notions intéressantes à-propos du serveur SSH, de certains
paramétrages clients nécessaires à faire, etc.</p>
</div>

<h2 id="configuration">Configuration</h2>
<h3 id="tunnel-ssh">Tunnel SSH</h3>
<p>Par défaut, l&rsquo;interface web LuCI n&rsquo;est disponible QUE sur le protocole































<span lang="en">HTTP <em>(HyperText Transfer Protocol)</em></span>
















































































, et en plus à l&rsquo;écoute partout ET sur toutes les interfaces !</p>
<p>Une manière de protéger est de rediriger le flux web vers l&rsquo;interface locale
de bouclage puis dans un tunnel SSH.</p>
<p>Aprés s&rsquo;être connecté en SSH à votre routeur OpenWRT :</p>
<ol>
<li>En premier lieu, sur OpenWRT, il nous faut reconfigurer le serveur web
<strong>uhttpd</strong>, pour lui dire de n&rsquo;écouter QUE localement sur le port 80.
Donc, éditez le fichier de configuration du serveur web <code>/etc/config/uhttpd</code>
pour :
<ul>
<li>mettre en commentaire les deux lignes : <code>list listen_http 0.0.0.0:80</code>
et <code>list listen_https   0.0.0.0:443</code> ; ajoutez en début de ligne
le symbole <code>#</code>.</li>
<li>puis ajoutez : <code>list listen_http  127.0.0.1:80</code><br>
<em>(et si vous voulez interrogez localhost sur IPv6 : <code>list listen_http [::1]:80</code>)</em></li>
<li>redémarrez le service web : <code>/etc/init.d/uhttpd restart</code></li>
<li>vérifiez que le service web n&rsquo;écoute bien que le port 80 sur l&rsquo;interface
locale :</li>
</ul>
</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ netstat -ant | grep -E <span style="color:#48b685">&#34;:80&#34;</span>
</span></span><span style="display:flex;"><span>tcp        <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span> 127.0.0.1:80            0.0.0.0:*               LISTEN
</span></span><span style="display:flex;"><span>tcp        <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span> ::1:80                  :::*                    LISTEN
</span></span></code></pre></div><ol start="2">
<li>Ensuite, la commande par défaut pour encapsuler dans SSH, du côté de
votre client SSH est :<br>
<code>ssh -L 127.0.0.1:8080:127.0.0.1:80 -p 22 id@ip-routeur</code><br>
Où :
<ul>
<li><code>-p 22</code> est le numéro du port d&rsquo;écoute par défaut du serveur SSH -
<em>par défaut, il n&rsquo;est même pas nécessaire de l&rsquo;écrire : si vous
l&rsquo;avez changé dans l&rsquo;administration, pensez à le modifier ici, aussi !</em></li>
<li><code>id</code> est l&rsquo;identifiant de votre 
<a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">nouvel utilisateur</a>
.</li>
<li><code>ip-routeur</code> est bien sûr l&rsquo;adresse IP(v4), côté LAN, de votre routeur OpenWRT !</li>
<li>Voici un exemple de configuration de votre fichier de config SSH du
côté de votre client :</li>
</ul>
</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Host luciweb</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Ciphers aes256-ctr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Hostname 192.168.1.1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">IdentityFile ~/.ssh/id_rsa</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">LocalForward 127.0.0.1:8080 127.0.0.1:80</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">MACs hmac-sha2-256</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Port 22</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">User identifiant</span>
</span></span></code></pre></div><p>Ainsi, vous n&rsquo;aurez plus qu&rsquo;à exécuter ainsi : <code>$ ssh luciweb</code></p>
<ul>
<li>Pour finir, dans votre navigateur web, écrivez l&rsquo;URL suivante : <code>localhost:8080</code></li>
</ul>
<p>Voilà !</p>
<h3 id="shell">Shell</h3>
<ul>
<li>Le fichier de configuration est situé dans : <code>/etc/config/dropbear</code></li>
<li>Le service de <strong>dropbear</strong> est lui accessible : <code>/etc/init.d/dropbear</code>.</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="error-no-matching-cipher-found-their-offer-aes128-ctraes256-ctr">Error: no matching cipher found. Their offer: aes128-ctr,aes256-ctr</h3>
<p>Le serveur SSH <strong>dropbear</strong> n&rsquo;est pas capable de gérer des chiffrements
forts autres que ceux restitués dans le message d&rsquo;erreur.</p>
<p>Ajoutez à votre configuration client SSH : <code>Ciphers aes256-ctr</code></p>
<h3 id="error-no-matching-host-key-type-found-their-offer-ssh-rsa">Error: no matching host key type found. Their offer: ssh-rsa</h3>
<p>Le serveur SSH <strong>dropbear</strong> n&rsquo;est pas capable de gérer des clés d&rsquo;hôtes
plus fortes autres que celles restituées dans le message d&rsquo;erreur.</p>
<p>Ajoutez à votre configuration client SSH : <code>HostKeyAlgorithms ssh-rsa</code></p>
<h3 id="error-no-matching-mac-found-their-offer-hmac-sha1hmac-sha2-256">Error: no matching MAC found. Their offer: hmac-sha1,hmac-sha2-256</h3>
<p>Le serveur SSH <strong>dropbear</strong> n&rsquo;est pas capable de gérer des algorithmes
forts, pour les <abbr title="Message Authentication Code">MAC</abbr>
, autres
que ceux restitués dans le message d&rsquo;erreur.</p>
<p>Ajoutez à votre configuration client SSH : <code>MACs hmac-sha2-256</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Paramétrer OpenWRT pour permettre une connexion sécurisée par SSH à l&#39;interface d&#39;administration LuCI]]></summary>
        <published>2020-02-26T15:44:44+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2d002ab7-92ba-165b-0342-33cb962884a2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/sudo/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : sudo</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="sudo" scheme="http://doc.huc.fr.eu.org/fr/tags/sudo/" />
        <category term="sysadmin" scheme="http://doc.huc.fr.eu.org/fr/tags/sysadmin/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par défaut, OpenWRT est livré avec un seul compte, celui de l&rsquo;administrateur <code>root</code>.</p>
<p>Nous allons créer un nouvel utilisateur sans privilège particulier qui
aura le droit d&rsquo;administrer le système par le biais de l&rsquo;utilitaire <code>sudo</code>.</p>
<h2 id="installation">Installation</h2>
<p>En tant que <strong>root</strong>, exécutons les commandes d&rsquo;installation suivantes :</p>
<pre tabindex="0"><code class="language-ash" data-lang="ash"># opkg update
# opkg install shadow-useradd sudo
</code></pre>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il est possible d&rsquo;installer aussi le paquet <code>shadow-usermod</code> qui permettra
au besoin de modifier tout paramètre lié au compte utilisateur.</div>

<h2 id="configuration">Configuration</h2>
<h3 id="configuration-utilisateur">configuration utilisateur</h3>
<p>Maintenant, configurons le compte utilisateur :</p>
<ul>
<li><code># u=username</code> où <code>username</code> est le nom d&rsquo;utilisateur choisi -
<em>à vous de paramètrer à votre convenance…</em></li>
<li><code># useradd &quot;${u}&quot;</code></li>
<li><code># passwd &quot;${u}&quot;</code> : afin de définir le mot-de-passe lié à l&rsquo;utilisateur</li>
<li><code># mkdir -p /home/&quot;${u}&quot;/.ssh</code> : pour créer le répertoire home principal,
ainsi que le sous-répertoire <code>.ssh</code> qui pourra servir plus tard.</li>
<li><code># touch /home/&quot;${u}&quot;/.ssh/authorized_keys</code> : créer le fichier vide nécessaire
pour y copier les clés SSH publiques.</li>
<li><code># chown -R &quot;${u}&quot;:&quot;${u}&quot; /home/&quot;${u}&quot;</code> : pour donner les droits d&rsquo;utilisateurs
sur son home.</li>
<li><code># chmod 0700 /home/&quot;${u}&quot;</code> : pour n&rsquo;autoriser que cet utilisateur dans son home.</li>
</ul>
<h3 id="configuration-sudo">configuration sudo</h3>
<p>Je ne parlerais que de la méthode la plus sécurisée de configuration de <code>sudo</code>. <br>
Cette méthode permet de n&rsquo;avoir qu&rsquo;à utiliser le mot de passe de l&rsquo;administrateur
sans avoir à se connecter avec le compte administrateur.
Une fois, connecté avec votre compte utilisateur, lors des besoins d&rsquo;administration,
il faudra précéder de la commande <code>sudo</code> toute autre commande nécessaire.</p>
<p>Avec l&rsquo;utilitaire <code>visudo</code>, nous allons éditer le fichier adéquate <code>/etc/sudoers</code>.</p>
<p><code># visudo</code></p>
<p>Puis dirigez vous vers la fin du fichier pour décommenter les deux lignes
suivantes, en supprimant le symbole <code>#</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Defaults targetpw  # Ask for the password of the target user</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ALL ALL=(ALL) ALL  # WARNING: only use this together with &#39;Defaults targetpw&#39;</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Pour ceux qui ne savent pas comment enregistrer avec l&rsquo;éditeur <strong>visudo</strong> :
tapez <code>:wq!</code> une fois que vous avez modifié le fichier afin d&rsquo;écrire celui-ci
et de quitter l&rsquo;éditeur.</div>

<p>Une fois l&rsquo;écriture validée, il sera permis à votre utilisateur <code>ego</code> d&rsquo;utiliser
toute commande d&rsquo;administration, telle que décrit ci-dessus.</p>
<h3 id="configuration-ssh">configuration ssh</h3>
<p>Profitez de ce moment particulier pour mettre votre <a class="inside" href="/fr/sec/ssh/configuration-securisee/#nouvelle-cl%c3%a9-rsa--pkbdf" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">clé d'authentification ssh</a>
,
dans le fichier <code>/home/ego/.ssh/authorized_keys</code>.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Assurez-vous de bien copier votre clé publique !</strong></div>

<h3 id="configuration-sauvegarde-système">configuration sauvegarde système</h3>
<p>Pensez à éditer le fichier <code>/etc/sysupgrade.conf</code> afin d&rsquo;ajouter :</p>
<ul>
<li>le répertoire home de votre utilisateur,</li>
<li><code>/etc/sudoers.d/</code> <em>(seulement si vous faites des ajouts dans ce répertoire)</em></li>
</ul>
<p>puis vérifier avec la commande <code>sysupgrade -l</code> que le répertoire est bien inclus.</p>
<p>Ainsi lors de votre futur 
<a class="inside" href="/fr/sys/openwrt/sysupgrade/" title="Lien interne vers l&#39;article : 'OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)'">mise à niveau</a>

d&rsquo;OpenWRT, vos données personnelles seront sauvegardées !</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://openwrt.org/docs/guide-user/security/secure.access#create_a_non-privileged_user_in_openwrt" rel="external">https://openwrt.org/docs/guide-user/security/secure.access#create_a_non-privileged_user_in_openwrt</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment créer un utilisateur non privilégié, lui permettre d&#39;avoir temporairement des droits privilégiés par le biais de sudo !?]]></summary>
        <published>2020-02-24T19:41:07+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:733f7407-6e28-3fe1-dce1-dfcf635484a8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/opkg-upgrade/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : opkg upgrade (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <category term="upgrade" scheme="http://doc.huc.fr.eu.org/fr/tags/upgrade/" />
        <category term="opkg" scheme="http://doc.huc.fr.eu.org/fr/tags/opkg/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="sysadmin" scheme="http://doc.huc.fr.eu.org/fr/tags/sysadmin/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>OpenWRT a pour gestionnaire de paquet l&rsquo;outil <code>opkg</code>.</p>
<p>Pour mettre à jour la liste des différents paquets, il n&rsquo;est pas prévu de mettre
à jour facilement ceux-ci en une seule ligne de commande, bien que l&rsquo;option
<code>upgrade</code> existe.</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>ATTENTION</strong> : L&rsquo;utilisation de l&rsquo;option <code>upgrade</code> est hautement découragée. <br>
Pour comprendre la raison, merci de lire la
<a href="https://openwrt.org/meta/infobox/upgrade_packages_warning" rel="external">page du wiki à ce propos</a> !</div>

<p>Voici l&rsquo;astuce :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># for name in `opkg list-upgradable | awk &#39;{print $1}&#39;`; do opkg upgrade &#34;${name}&#34;; done</span>
</span></span></code></pre></div><p>Ou si comme moi, vous avez créé un utilisateur qui a le droit d&rsquo;utiliser la
commande <code>sudo</code>, faites simplement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ <span style="color:#815ba4">for</span> name in <span style="color:#48b685">`</span>sudo opkg list-upgradable | awk <span style="color:#48b685">&#39;{print $1}&#39;</span><span style="color:#48b685">`</span>; <span style="color:#815ba4">do</span> sudo opkg upgrade <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><hr>
<h3 id="script">Script</h3>
<p>Un petit scrip shell nommé <code>opkgupgrade.sh</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>sudo opkg update
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> name in <span style="color:#48b685">`</span>sudo opkg list-upgradable | awk <span style="color:#48b685">&#39;{print $1}&#39;</span><span style="color:#48b685">`</span>; <span style="color:#815ba4">do</span> sudo opkg upgrade <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">name</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><p>Il n&rsquo;y a plus qu&rsquo;à l&rsquo;appeler : &lt;<br>
<code>$ ./opkgupgrade.sh</code></p>
<p>Et voilà !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre à jour l&#39;ensemble de la liste des packages sous OpenWRT avec le gestionnaire opkg]]></summary>
        <published>2020-02-24T19:17:42+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b59e70e3-87e9-6bec-96f2-1481def1313e</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/reed-alert-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Reed-alert : Monitorer simplement OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong>Reed-alert</strong> est un projet de monitoring simple sous OpenBSD, il
n&rsquo;enregistre aucune donnée ni ne produit des graphes de visualisation.</p>
<p>À partir d&rsquo;un fichier de configuration, il vérifie plusieurs états et si
ceux-ci échouent alors il sera envoyé une alerte. Le langage utilisée est
le Lisp.</p>
<hr>
<ul>
<li>
<p>Auteure : <a href="https://dataswamp.org/~solene/2018-01-17-reed-alert.html" rel="external">Solène Rapenne</a></p>
</li>
<li>
<p>dépôt Git : git://bitreich.org/reed-alert</p>
</li>
<li>
<p><a href="https://dataswamp.org/~solene/2018-01-17-reed-alert.html" rel="external">présentation de reed-alert</a> <em>(en anglais)</em></p>
</li>
<li>
<p><a href="https://dataswamp.org/~solene/2022-02-10-five-years-of-reed-alert.html" rel="external">constat au bout de cinq ans</a>… <em>(en anglais)</em></p>
</li>
</ul>
<h2 id="installation">Installation</h2>
<h3 id="paquet">Paquet</h3>
<p>L&rsquo;installation est très simple en soit : <code># pkg_add reed-alert</code></p>
<ul>
<li>OpenBSD : <del>6.6</del> → <strong>7.2</strong></li>
<li>Version : <strong>1.05</strong></li>
</ul>
<p>Vous pouvez préférer le code sur le dépôt <a href="/fr/monitor/reed-alert-openbsd/#git">git</a> qui corrige quelques
détails.</p>
<h3 id="git">git</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ git clone git://bitreich.org/reed-alert
</span></span><span style="display:flex;"><span>:$ cd reed-alert
</span></span><span style="display:flex;"><span>:$ make
</span></span><span style="display:flex;"><span>sed <span style="color:#48b685">&#39;s,REEDDIR=,&amp;/usr/local/share/reed-alert/,&#39;</span> reed-alert.in &gt; reed-alert
</span></span><span style="display:flex;"><span>:$ doas make install
</span></span><span style="display:flex;"><span>mkdir -p /usr/local/share/reed-alert/
</span></span><span style="display:flex;"><span>mkdir -p /usr/local/bin
</span></span><span style="display:flex;"><span>install -o root -g bin -m <span style="color:#f99b15">755</span> reed-alert /usr/local/bin/reed-alert
</span></span><span style="display:flex;"><span>install -o root -g wheel -m <span style="color:#f99b15">644</span> probes.lisp functions.lisp /usr/local/share/reed-alert//
</span></span></code></pre></div><p>L&rsquo;avantage du dépôt est qu&rsquo;il fourni le fichier <strong>README</strong> très explicatif,
ainsi que des fichiers d&rsquo;exemples, ainsi qu&rsquo;un
<a href="/fr/monitor/reed-alert-openbsd/#sortie-html">outil de sortie au format HTML</a>.</p>
<h3 id="dépendance">Dépendance</h3>
<ul>
<li>le paquet <strong>ecl</strong> : <code># pkg_add ecl</code> — <em>qui est normalement installé en
dépendance du paquet reed-alert</em>.</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Le fichier <code>README</code> vous informe que vous pouvez copier l&rsquo;un des deux
fichiers exemples en fichier de configuration.
Faisons simple, en admettons que nous soyons dans le répertoire de <strong>reed-alert</strong> : <br>
<code>:$ touch config.lisp</code>.</p>
<p>Il vous faudra ensuite l&rsquo;éditer avec votre éditeur de texte favori.</p>
<h3 id="cron">cron</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Assurez-vous que la variable d&rsquo;environnement <code>PATH</code> dans votre crontab
comporte aussi le répertoire <code>/usr/local/bin</code>.</div>

<p>Une fois que vous aurez tout configuré, et <a href="/fr/monitor/reed-alert-openbsd/#vérification">vérifiez</a>
que votre configuration soit sans erreur,  n&rsquo;hésitez pas à ouvrir la table
de cron de l&rsquo;utilisateur <code>root</code> pour y ajouter un job de surveillance,
tel que :</p>
<p><code>*/5 *   *   *   *   -ns reed-alert /repertoire-vers/reed-alert/config.lisp</code></p>
<p>où :</p>
<ul>
<li>
<p>les deux options <code>-ns</code> sont spécifiques à la gestion cron - <br>
<em>cf la partie <a href="/fr/monitor/reed-alert-openbsd/#documentations">Documentations</a></em></p>
</li>
<li>
<p><code>/repertoire-vers/reed-alert/</code> correspond au répertoire où vous aurez
créé/déposé votre <a href="/fr/monitor/reed-alert-openbsd/#configuration">fichier de configuration</a></p>
</li>
<li>
<p>cette tâche s&rsquo;exécutera toutes les 5 minutes ; à vous de voir, si cette
période vous est utile/nécessaire, et de la modifier en conséquence.</p>
</li>
</ul>
<h3 id="langage">Langage</h3>
<p>C&rsquo;est du Common LISP !</p>
<p>Hormis les variables et les preuves déjà prédéfinies, il est possible
d&rsquo;utiliser des concepts de condition, de boucles, d&rsquo;imbriquer des dépendances,
des niveaux d&rsquo;échelles d&rsquo;alertes, d&rsquo;étendre/créer vos propres preuves.
Tout cela est expliqué clairement dans le fichier <strong>README</strong>.</p>
<h4 id="variables-prédéfinies">Variables prédéfinies</h4>
<p>Il existe des variables prédéfinies, elles sont entourées du symbole modulo
<code>%</code> et peuvent être utilisées partout dans votre fichier de configuration.</p>
<p>Voici leurs noms et leur définition :</p>
<ul>
<li>
<p><code>%function%</code>    : le nom de la fonction qui sert de preuve</p>
</li>
<li>
<p><code>%date%</code>        : la date actuelle au format YYYY/MM/DD hh:mm:ss</p>
</li>
<li>
<p><code>%params%</code>      : les paramètres utilisés dans le contexte de la preuve</p>
</li>
<li>
<p><code>%hostname%</code>    : le nom d&rsquo;hôte</p>
</li>
<li>
<p><code>%result%</code>      : l&rsquo;erreur retournée (tel que la valeur excédant la limite,
un fichier non trouvé, etc… )</p>
</li>
<li>
<p><code>%desc%</code>        : une description arbitraire nommant une vérification ;
par défaut, est une chaîne vide</p>
</li>
<li>
<p><code>%level%</code>       : le type de la notification utilisé</p>
</li>
<li>
<p><code>%os%</code>          : le système d&rsquo;exploitation utilisé (FreeBSD/Linux/OpenBSD)</p>
</li>
<li>
<p><code>%newline%</code>     : le caractère de nouvelle ligne</p>
</li>
<li>
<p><code>%state%</code>       : les états &ldquo;start&rdquo; / &ldquo;end&rdquo; lorsqu&rsquo;un problème est levé ou
résolu.</p>
</li>
</ul>
<h4 id="preuve">Preuve</h4>
<p>La preuve est en fait un type de vérification à effectuer. C&rsquo;est un test !</p>
<p>Par défaut, il est possible de vérifier :</p>
<ul>
<li>
<p><code>command</code> : exécute une commande arbitraire, désirée par l&rsquo;administrateur,
et qui déclenchera une alerte si le code d&rsquo;erreur est supérieur à zéro.</p>
</li>
<li>
<p><code>curl-http-status</code> : exécute une requête HTTP et lève une alerte si le
code de retour est différent de &lsquo;OK&rsquo; <em>(code 200)</em></p>
</li>
<li>
<p><code>disk-usage</code> : que la taille d&rsquo;une partition n&rsquo;excéde pas une certaine limite</p>
</li>
<li>
<p><code>file-exists</code> : qu&rsquo;un certain fichier existe</p>
</li>
<li>
<p><code>file-less-than</code></p>
</li>
<li>
<p><code>file-updated</code> : qu&rsquo;un certain fichier existe et qu&rsquo;il a été mis à jour
depuis un temps défini</p>
</li>
<li>
<p><code>load-average-1</code> : que la charge moyenne durant la dernière minute
n&rsquo;excéde pas une certaine limite</p>
</li>
<li>
<p><code>load-average-5</code> : que la charge moyenne durant les cinq dernières minutes
n&rsquo;excéde pas une certaine limite</p>
</li>
<li>
<p><code>load-average-15</code> : que la charge moyenne durant les quinze dernières
minutes n&rsquo;excéde pas une certaine limite</p>
</li>
<li>
<p><code>number-of-processes</code> : le nombre de processus n&rsquo;excède pas une certaine limite.</p>
</li>
<li>
<p><code>pid-running</code> : le processus en question soit vivant, en spécifiant le
fichier d&rsquo;identifiant de processus.</p>
</li>
<li>
<p><code>ping</code> : que l&rsquo;hôte distant répond à deux ping.</p>
</li>
<li>
<p><code>service</code> : qu&rsquo;un service soit actif sur le système hôte</p>
</li>
<li>
<p><code>ssl-expiration</code> : qu&rsquo;un certificat SSL expire dans une période donnée
en nombre de secondes.</p>
</li>
<li>
<p><code>write-to-file</code> : permet d&rsquo;écrire du contenu dans un fichier ; le créera
s&rsquo;il n&rsquo;existe pas localement.</p>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Évitez d&rsquo;utiliser ces mots clés dans vos propres variables, vous pourriez
avoir à gérer des <a href="/fr/monitor/reed-alert-openbsd/#dépannage">erreurs</a> bien truculentes !</div>

<p>Je vous renvoie à la lecture du fichier <strong>README</strong> pour en savoir plus
sur chacune de ces preuves.</p>
<h3 id="ajout-de-lalerte">Ajout de l&rsquo;alerte</h3>
<p>La première chose à faire est d&rsquo;ajouter une alerte - pour nous faciliter
le propos, nous créerons une alerte mail.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Sachez qu&rsquo;il est possible de créer des alertes de type SMS, des alertes
qui n&rsquo;avertissent de rien, ou tout autre sorte d&rsquo;alerte que vous pourriez
inventer.</div>

<p>Ajoutez basiquement : <br>
<code>(alert mail &quot;echo 'problem on %hostname%' | mail mail@domain.tld&quot;)</code></p>
<p>Une version plus élaborée : <br>
<code>(alert mail &quot;echo -n '[%state%] Problem with %function% %date% %params%' | mail -s '[%state%] alarm on %hostname%' mail@domain.tld&quot;)</code></p>
<h3 id="sortie-html">Sortie HTML</h3>
<p>La version du dépôt <a href="/fr/monitor/reed-alert-openbsd/#git">git</a> fournit un outil de sortie au
format HTML que l&rsquo;on trouve dans le répertoire enfant <code>extras/output2html.sh</code>.</p>
<p>Voici comment l&rsquo;utiliser : <br>
<code>$ reed-alert config.lisp | extras/output2html.sh &gt; alert.html</code></p>
<p>Il ne vous reste plus qu&rsquo;à mettre/fournir ce fichier html sur un espace
web pour obtenir la lecture de celui-ci.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Configurez votre <a href="/fr/monitor/reed-alert-openbsd/#cron">crontab</a> en ajoutant l&rsquo;outil de sortie HTML.</div>

<h3 id="exemples">Exemples</h3>
<p>Pour rappel, allez lire les deux fichiers d&rsquo;exemples fournis par le projet.
Ils sont instructifs.</p>
<p>Ci-dessous, retrouvez des exemples de mon cru.</p>
<h4 id="exemple--curl-http-status">Exemple : <code>curl-http-status</code></h4>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Pour cibler un serveur délivrant sur le protocole</p>
<p><span lang="en">HTTPS <em>(HyperText Transfer Protocol Secure)</em></span></p>
<p>,
il est nécessaire de le cibler en le précédent du schéma suivant :
<code>https://</code> suivi du nom de domaine à cibler.</p>
</div>

<p>⇒ version basique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">curl-http-status</span> <span style="color:#48b685">:url</span> <span style="color:#48b685">&#34;huc.fr.eu.org&#34;</span> <span style="color:#48b685">:timeout</span> <span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">curl-http-status</span> <span style="color:#48b685">:url</span> <span style="color:#48b685">&#34;openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">:timout</span> <span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">curl-http-status</span> <span style="color:#48b685">:url</span> <span style="color:#48b685">&#34;blog.openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">:timeout</span> <span style="color:#f99b15">3</span>)
</span></span></code></pre></div><p>⇒ version élaborée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(loop <span style="color:#ef6155">for</span> <span style="color:#ef6155">host</span> <span style="color:#ef6155">in</span> (<span style="color:#fec418">list</span> <span style="color:#48b685">&#34;huc.fr.eu.org&#34;</span> <span style="color:#48b685">&#34;openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">&#34;blog.openbsd.fr.eu.org&#34;</span>)
</span></span><span style="display:flex;"><span>    do
</span></span><span style="display:flex;"><span>        (<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">curl-http-status</span> <span style="color:#48b685">:url</span> <span style="color:#ef6155">host</span> <span style="color:#48b685">:timeout</span> <span style="color:#f99b15">3</span>))
</span></span></code></pre></div><p>⇒ Exemple de retour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>MAIL    CURL-HTTP-STATUS    URL https://huc.fr.eu.org TIMEOUT <span style="color:#f99b15">3</span>         SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    CURL-HTTP-STATUS    URL https://openbsd.fr.eu.org TIMEOUT <span style="color:#f99b15">3</span>         SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    CURL-HTTP-STATUS    URL https://blog.openbsd.fr.eu.org TIMEOUT <span style="color:#f99b15">3</span>        SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span></code></pre></div><h4 id="exemple--disk-usage">Exemple : <code>disk-usage</code></h4>
<p>Là, je vous ferais direct la version élaborée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(loop <span style="color:#ef6155">for</span> <span style="color:#ef6155">path</span> <span style="color:#ef6155">in</span> (<span style="color:#ef6155">uiop:run-program</span> <span style="color:#48b685">&#34;mount | awk -v pattern=&#39;/&#39; &#39;$0 ~ pattern { print $3 }&#39; &#34;</span> <span style="color:#48b685">:output</span> <span style="color:#48b685">:lines</span>)
</span></span><span style="display:flex;"><span>    do
</span></span><span style="display:flex;"><span>        (<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">disk-usage</span> <span style="color:#48b685">:path</span> <span style="color:#ef6155">path</span> <span style="color:#48b685">:limit</span> <span style="color:#f99b15">80</span>))
</span></span></code></pre></div><p><strong>Explication</strong> :</p>
<ul>
<li>La boucle appele la commande <code>mount</code> qui est &ldquo;filtrée&rdquo; par la commande
<code>awk</code> afin de ne restituer que le nom des partitions existantes, sur
lesquelles sera appliqué le test de preuve.</li>
</ul>
<p>⇒ Exemple de retour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH / LIMIT <span style="color:#f99b15">80</span>         SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /home LIMIT <span style="color:#f99b15">80</span>         SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /tmp LIMIT <span style="color:#f99b15">80</span>      SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /usr LIMIT <span style="color:#f99b15">80</span>      SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /usr/X11R6 LIMIT <span style="color:#f99b15">80</span>        SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /usr/local LIMIT <span style="color:#f99b15">80</span>        SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /usr/obj LIMIT <span style="color:#f99b15">80</span>      SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /usr/src LIMIT <span style="color:#f99b15">80</span>      SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    DISK-USAGE  PATH /var LIMIT <span style="color:#f99b15">80</span>      SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span></code></pre></div><h4 id="exemple--ping">Exemple : <code>ping</code></h4>
<p>⇒ version basique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">ping</span> <span style="color:#48b685">:host</span> <span style="color:#48b685">&#34;192.168.1.1&#34;</span> <span style="color:#48b685">:desc</span> <span style="color:#48b685">&#34;Ping 192.168.1.1&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">ping</span> <span style="color:#48b685">:host</span> <span style="color:#48b685">&#34;huc.fr.eu.org&#34;</span> <span style="color:#48b685">:desc</span> <span style="color:#48b685">&#34;Ping huc.fr.eu.org&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">ping</span> <span style="color:#48b685">:host</span> <span style="color:#48b685">&#34;openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">:desc</span> <span style="color:#48b685">&#34;Ping openbsd.fr.eu.org&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">ping</span> <span style="color:#48b685">:host</span> <span style="color:#48b685">&#34;blog.openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">:desc</span> <span style="color:#48b685">&#34;Ping blog.openbsd.fr.eu.org&#34;</span>)
</span></span></code></pre></div><p>⇒ version élaborée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(loop <span style="color:#ef6155">for</span> <span style="color:#ef6155">host</span> <span style="color:#ef6155">in</span> (<span style="color:#fec418">list</span> <span style="color:#48b685">&#34;192.168.1.1&#34;</span> <span style="color:#48b685">&#34;huc.fr.eu.org&#34;</span> <span style="color:#48b685">&#34;openbsd.fr.eu.org&#34;</span> <span style="color:#48b685">&#34;blog.openbsd.fr.eu.org&#34;</span>)
</span></span><span style="display:flex;"><span>    do
</span></span><span style="display:flex;"><span>        (<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">ping</span> <span style="color:#48b685">:host</span> <span style="color:#ef6155">host</span>))
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Vous voulez personnaliser le message avec un texte prédéfini, tel que<code>Ping :</code>,
utilisez la fonction <code>concatenate</code>, en ajoutant une description dans la dernière
ligne, tel que : <br>
<code>:desc (concatenate 'string &quot;Ping : &quot; host)</code></div>

<p>⇒ Exemple de retour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>MAIL    PING    HOST 192.168.1.1    Ping : 192.168.1.1  SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    PING    HOST huc.fr.eu.org  Ping : huc.fr.eu.org    SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    PING    HOST openbsd.fr.eu.org  Ping : openbsd.fr.eu.org    SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    PING    HOST blog.openbsd.fr.eu.org     Ping : blog.openbsd.fr.eu.org   SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span></code></pre></div><h4 id="exemple--service">Exemple : <code>service</code></h4>
<p>⇒ version basique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;ntpd&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;pflogd&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;smbd&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;smtpd&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;sshd&#34;</span>)
</span></span><span style="display:flex;"><span>(<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#48b685">&#34;syslogd&#34;</span>)
</span></span></code></pre></div><p>⇒ version élaborée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-lisp" data-lang="lisp"><span style="display:flex;"><span>(loop <span style="color:#ef6155">for</span> <span style="color:#ef6155">name</span> <span style="color:#ef6155">in</span> (<span style="color:#fec418">list</span> <span style="color:#48b685">&#34;ntpd&#34;</span> <span style="color:#48b685">&#34;pflogd&#34;</span> <span style="color:#48b685">&#34;smbd&#34;</span> <span style="color:#48b685">&#34;sshd&#34;</span> <span style="color:#48b685">&#34;syslogd&#34;</span>)
</span></span><span style="display:flex;"><span>    do
</span></span><span style="display:flex;"><span>        (<span style="color:#ef6155">=&gt;</span> <span style="color:#ef6155">mail</span> <span style="color:#ef6155">service</span> <span style="color:#48b685">:name</span> <span style="color:#ef6155">name</span>))
</span></span></code></pre></div><p>⇒ Exemple de retour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>MAIL    SERVICE NAME ntpd       SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    SERVICE NAME pflogd         SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    SERVICE NAME smbd       SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    SERVICE NAME sshd       SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>MAIL    SERVICE NAME syslogd        SUCCESS SUCCESS NO  <span style="color:#f99b15">0</span>
</span></span></code></pre></div><h2 id="vérification">Vérification</h2>
<p>Pour vérifier l&rsquo;écriture de votre fichier de configuration, une fois que celle-ci
est terminée/modifiée, exécutez simplement en console : <br>
<code>:$ reed-alert /repertoire-vers/reed-alert/config.lisp</code></p>
<p>Une fois que votre vérification est faite, pensez à <a href="/fr/monitor/reed-alert-openbsd/#cron">créer une tâche cron</a>
;-)</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="the-character--is-not-a-valid-dispatch-macro-character">The character *** is not a valid dispatch macro character.</h3>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>An error occurred during initialization:
</span></span><span style="display:flex;"><span>Reader error in file <span style="color:#776e71">#&lt;input stream #P/path/reed-alert/config.lisp&#34; 0xa5b677d1960&gt;, position 173:</span>
</span></span><span style="display:flex;"><span>The character Space is not a valid dispatch macro character.
</span></span></code></pre></div><p>Vérifiez vos écritures. Vous avez certainement fait une erreur typographique…</p>
<h3 id="ecl-or-sbcl-not-found-in-path">ecl or sbcl not found in PATH.</h3>
<p>Vous avez le message suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>ecl or sbcl not found in PATH.
</span></span><span style="display:flex;"><span>you need at least one of them to use reed-alert
</span></span></code></pre></div><p>Après vous être assuré d&rsquo;avoir au moins <a href="/fr/monitor/reed-alert-openbsd/#dépendance">installer le paquet ecl</a>,
ajoutez dans la variable d&rsquo;environnement <code>PATH</code> de votre crontab le
répertoire <code>/usr/local/bin</code>.</p>
<h3 id="name-is-not-of-type-function">&rsquo;name&rsquo; is not of type FUNCTION..</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>An error occurred during initialization:
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;name&#34;</span> is not of type FUNCTION.
</span></span></code></pre></div><p>Vous utilisez une boucle ? <br>
Il y a de forte probabilité que vous ayez utilisé un nom de variable
similaire à celui d&rsquo;une fonction !</p>
<h3 id="not-a-valid-property-list">Not a valid property list</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>An error occurred during initialization:
</span></span><span style="display:flex;"><span>Not a valid property list <span style="color:#5bc4bf">(</span>HOST Ping  192.168.1.3<span style="color:#5bc4bf">)</span>.
</span></span></code></pre></div><p>Vous utilisez une boucle ? <br>
Vérifiez l&rsquo;écriture de votre boucle, une des propriétés n&rsquo;est pas correcte.</p>
<h3 id="unexpected-end-of-file-on">Unexpected end of file on</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>An error occurred during initialization:
</span></span><span style="display:flex;"><span>Unexpected end of file on <span style="color:#776e71">#&lt;input stream #P&#34;/path/reed-alert/config.lisp&#34;&gt;.</span>
</span></span></code></pre></div><p>L&rsquo;erreur ci-dessus est due à une mauvaise écriture dans votre fichier de
configuration ! <br>
Donc, <span class="red">VÉRIFIEZ, vérifiez ET vérifiez encore, et encore
</span>
 ce que vous avez écrit : un simple oubli d&rsquo;une parenthèse
fermante, d&rsquo;un apostrophe/guillemet peut en être la cause.</p>
<h2 id="documentations">Documentations</h2>
<p>La copie du dépôt vous permettra de lire les fichiers suivants :</p>
<ul>
<li>
<p><code>README</code> : À lire, très complet, il fournit en anglais, les différentes
étapes d&rsquo;installation, de paramétrage, et autres exemples.</p>
</li>
<li>
<p>les fichiers d&rsquo;exemple : <code>example-simple.lisp</code> et <code>example-full.lisp</code>.</p>
</li>
</ul>
<hr>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/crontab.5" title="Page du Manuel OpenBSD pour : crontab">crontab(5)</a>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>Solène Rapenne fait partie de l&rsquo;équipe des développeurs d&rsquo;OpenBSD.
Informaticienne, elle développe dans plusieurs langages, dont le Lisp qui
est la base du code de <strong>reed-alert</strong>, et à ses heures perdues professionnellement
parlant absolument la fonction d&rsquo;administrateur réseaux/système! :p</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mettre en place simplement du monitoring d&#39;OpenBSD, en mode console/terminal, avec un simple fichier de configuration grâce au projet &#39;Reed-alert&#39;]]></summary>
        <published>2020-02-24T01:27:09+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:76c9a008-3294-6a71-fc04-66eb91d020e5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/mate/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MATE (environnement de bureau graphique) / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="MATE" scheme="http://doc.huc.fr.eu.org/fr/tags/mate/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>MATE</strong> est un environnement de bureau graphique.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 la base
et les quelques utilitaires</strong> (<em>optionnels</em>) : <code>mate mate-extras</code></p>
<h2 id="configuration">Configuration</h2>
<h3 id="démarrage-session-graphique">Démarrage session graphique</h3>
<p>Il est nécessaire de configurer votre fichier de session <code>.xsession</code>
pour y inclure ceci :</p>
<p><code>exec /usr/local/bin/ck-launch-session /usr/local/bin/mate-session</code></p>
<h3 id="gestionnaire-dénergie">Gestionnaire d&rsquo;énergie</h3>
<p>Afin de fonctionner correctement cette fonctionnalité, MATE a besoin que
le service <code>system-wide D-Bus</code> soit opérationnel.</p>
<p>Veuillez lire les informations sur la page
<a class="inside" href="/fr/sys/openbsd/consolekit/#d%c3%a9marrage-de-service-n%c3%a9cessaire" title="Lien interne vers l&#39;article : 'Consolekit2 (bus de messages) / OpenBSD'">ConsoleKit2</a>
.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le bureau graphique nommé &#39;MATE&#39; sous OpenBSD]]></summary>
        <published>2020-02-21T22:46:45+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2dadac69-99e6-4978-147c-08270a89b6fc</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/slim/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SLiM / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="SLiM" scheme="http://doc.huc.fr.eu.org/fr/tags/slim/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong><a href="https://github.com/data-modul/slim" rel="external">SLiM</a></strong> est un gestionnaire de
session graphique indépendant du Bureau pour X11, dérivé de Login.app.</p>
<p>Il clame être léger et simple, bien que complètement configurable
au-travers de thèmes et d&rsquo;un fichier option. Il convient pour les machines
sur lesquelles la fonctionnalité de session à distance n&rsquo;est pas nécessaire.</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p><strong>ATTENTION</strong> : ce logiciel n&rsquo;est plus maintenu officiellement depuis 2015 !</p>
<p>De plus, depuis OpenBSD 6.1, le gestionnaire de session officiel
<a class="inside" href="/fr/sys/openbsd/xenodm/" title="Lien interne vers l&#39;article : 'xenodm : Gestionnaire de sessions X pour OpenBSD'">xenodm</a>
est embarqué !</p>
</div>

<h2 id="installation">Installation</h2>
<p>Il était possible d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

le paquet <code>slim</code> ; les thèmes sont disponibles dans le paquet <code>slim-themes</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le gestionnaire de session graphique, nommé &#39;SLiM&#39;, sous OpenBSD.]]></summary>
        <published>2020-02-21T22:13:29+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:938ff3b5-0d0a-d976-a730-c86b0045466d</id>
        <link href="http://doc.huc.fr.eu.org/fr/don/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Page de dons</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Don" scheme="http://doc.huc.fr.eu.org/fr/tags/don/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Vous appréciez mes articles pour la qualité, leur sérieux, et vous voulez
faire un petit geste sympa, tel le prix d&rsquo;un café, d&rsquo;une bierre… <br>
Ou, juste pour me remercier, et m&rsquo;encourager ;-) :p</p>
<p>Faites un don, tout simplement.</p>
<p><strong>Merci d&rsquo;avance</strong> :D</p>
<p>⇒ Si vous le faites, et si vous le souhaitez votre nom, ou pseudo sera
affiché ici, avec votre accord, à la date du don.</p>
<p>⇒ Alors, si vous le désirez, faites-le moi savoir dans votre don ;)</p>
<h2 id="comment">Comment</h2>
<h3 id="ko-fi">Ko-fi</h3>
<ul>
<li><a href="https://ko-fi.com/hucste" rel="external">https://ko-fi.com/hucste</a></li>
</ul>


<figure class="pure-img">
    <a href="/svg/qrcode/ko-fi.svg" title="Et, un Ko-fi pour Stéphane HUC">
    <svg xmlns="http://www.w3.org/2000/svg" class="qr-svg " height="128" viewBox="0 0 53 53" width="128">
<defs><style>rect{shape-rendering:crispEdges}</style></defs>
<path class="qr-4 " stroke="transparent" fill="#fff" fill-opacity="1" d="M16 4 h2 v1 h-2Z M19 4 h1 v1 h-1Z M24 4 h1 v1 h-1Z M28 4 h1 v1 h-1Z M30 4 h2 v1 h-2Z M36 4 h1 v1 h-1Z M13 5 h4 v1 h-4Z M20 5 h2 v1 h-2Z M23 5 h1 v1 h-1Z M25 5 h2 v1 h-2Z M29 5 h1 v1 h-1Z M31 5 h4 v1 h-4Z M37 5 h1 v1 h-1Z M14 6 h3 v1 h-3Z M19 6 h1 v1 h-1Z M21 6 h2 v1 h-2Z M24 6 h3 v1 h-3Z M29 6 h4 v1 h-4Z M36 6 h1 v1 h-1Z M13 7 h3 v1 h-3Z M17 7 h3 v1 h-3Z M21 7 h4 v1 h-4Z M26 7 h3 v1 h-3Z M30 7 h1 v1 h-1Z M32 7 h1 v1 h-1Z M35 7 h2 v1 h-2Z M13 8 h1 v1 h-1Z M19 8 h1 v1 h-1Z M21 8 h2 v1 h-2Z M29 8 h5 v1 h-5Z M36 8 h1 v1 h-1Z M14 9 h1 v1 h-1Z M17 9 h4 v1 h-4Z M22 9 h1 v1 h-1Z M29 9 h1 v1 h-1Z M33 9 h1 v1 h-1Z M35 9 h3 v1 h-3Z M14 11 h3 v1 h-3Z M20 11 h4 v1 h-4Z M31 11 h1 v1 h-1Z M34 11 h4 v1 h-4Z M39 11 h1 v1 h-1Z M14 12 h1 v1 h-1Z M17 12 h3 v1 h-3Z M33 12 h2 v1 h-2Z M37 12 h1 v1 h-1Z M39 12 h1 v1 h-1Z M5 13 h3 v1 h-3Z M11 13 h1 v1 h-1Z M13 13 h3 v1 h-3Z M20 13 h4 v1 h-4Z M25 13 h1 v1 h-1Z M30 13 h3 v1 h-3Z M34 13 h2 v1 h-2Z M38 13 h1 v1 h-1Z M40 13 h1 v1 h-1Z M45 13 h1 v1 h-1Z M47 13 h2 v1 h-2Z M4 14 h2 v1 h-2Z M8 14 h2 v1 h-2Z M13 14 h4 v1 h-4Z M18 14 h2 v1 h-2Z M26 14 h2 v1 h-2Z M33 14 h1 v1 h-1Z M39 14 h5 v1 h-5Z M4 15 h2 v1 h-2Z M7 15 h1 v1 h-1Z M12 15 h4 v1 h-4Z M21 15 h2 v1 h-2Z M24 15 h2 v1 h-2Z M28 15 h2 v1 h-2Z M33 15 h1 v1 h-1Z M36 15 h3 v1 h-3Z M40 15 h6 v1 h-6Z M47 15 h1 v1 h-1Z M6 16 h1 v1 h-1Z M8 16 h1 v1 h-1Z M12 16 h1 v1 h-1Z M16 16 h2 v1 h-2Z M22 16 h5 v1 h-5Z M35 16 h4 v1 h-4Z M41 16 h2 v1 h-2Z M44 16 h1 v1 h-1Z M5 17 h4 v1 h-4Z M12 17 h1 v1 h-1Z M17 17 h1 v1 h-1Z M19 17 h2 v1 h-2Z M22 17 h1 v1 h-1Z M25 17 h1 v1 h-1Z M28 17 h1 v1 h-1Z M30 17 h1 v1 h-1Z M32 17 h2 v1 h-2Z M36 17 h4 v1 h-4Z M42 17 h5 v1 h-5Z M48 17 h1 v1 h-1Z M4 18 h1 v1 h-1Z M8 18 h2 v1 h-2Z M12 18 h5 v1 h-5Z M19 18 h2 v1 h-2Z M22 18 h5 v1 h-5Z M28 18 h1 v1 h-1Z M31 18 h1 v1 h-1Z M35 18 h2 v1 h-2Z M44 18 h2 v1 h-2Z M47 18 h2 v1 h-2Z M5 19 h1 v1 h-1Z M8 19 h2 v1 h-2Z M11 19 h1 v1 h-1Z M13 19 h1 v1 h-1Z M16 19 h4 v1 h-4Z M22 19 h3 v1 h-3Z M28 19 h1 v1 h-1Z M34 19 h2 v1 h-2Z M37 19 h1 v1 h-1Z M39 19 h1 v1 h-1Z M44 19 h1 v1 h-1Z M48 19 h1 v1 h-1Z M4 20 h3 v1 h-3Z M11 20 h2 v1 h-2Z M19 20 h3 v1 h-3Z M23 20 h4 v1 h-4Z M30 20 h5 v1 h-5Z M36 20 h1 v1 h-1Z M40 20 h1 v1 h-1Z M42 20 h2 v1 h-2Z M46 20 h3 v1 h-3Z M4 21 h2 v1 h-2Z M8 21 h2 v1 h-2Z M11 21 h2 v1 h-2Z M14 21 h1 v1 h-1Z M16 21 h1 v1 h-1Z M19 21 h1 v1 h-1Z M23 21 h1 v1 h-1Z M27 21 h3 v1 h-3Z M32 21 h1 v1 h-1Z M34 21 h4 v1 h-4Z M41 21 h2 v1 h-2Z M46 21 h2 v1 h-2Z M6 22 h2 v1 h-2Z M9 22 h1 v1 h-1Z M12 22 h1 v1 h-1Z M14 22 h4 v1 h-4Z M20 22 h2 v1 h-2Z M25 22 h2 v1 h-2Z M29 22 h1 v1 h-1Z M33 22 h1 v1 h-1Z M36 22 h1 v1 h-1Z M38 22 h2 v1 h-2Z M41 22 h1 v1 h-1Z M43 22 h1 v1 h-1Z M45 22 h4 v1 h-4Z M4 23 h1 v1 h-1Z M6 23 h2 v1 h-2Z M9 23 h1 v1 h-1Z M11 23 h2 v1 h-2Z M14 23 h1 v1 h-1Z M16 23 h1 v1 h-1Z M20 23 h3 v1 h-3Z M24 23 h4 v1 h-4Z M29 23 h3 v1 h-3Z M33 23 h1 v1 h-1Z M35 23 h1 v1 h-1Z M38 23 h5 v1 h-5Z M48 23 h1 v1 h-1Z M4 24 h2 v1 h-2Z M13 24 h2 v1 h-2Z M18 24 h1 v1 h-1Z M20 24 h1 v1 h-1Z M35 24 h5 v1 h-5Z M45 24 h3 v1 h-3Z M4 25 h4 v1 h-4Z M17 25 h2 v1 h-2Z M20 25 h1 v1 h-1Z M22 25 h1 v1 h-1Z M33 25 h1 v1 h-1Z M38 25 h1 v1 h-1Z M46 25 h2 v1 h-2Z M6 26 h2 v1 h-2Z M14 26 h1 v1 h-1Z M20 26 h1 v1 h-1Z M29 26 h1 v1 h-1Z M37 26 h3 v1 h-3Z M45 26 h2 v1 h-2Z M48 26 h1 v1 h-1Z M5 27 h1 v1 h-1Z M14 27 h9 v1 h-9Z M30 27 h1 v1 h-1Z M33 27 h1 v1 h-1Z M35 27 h3 v1 h-3Z M39 27 h1 v1 h-1Z M46 27 h3 v1 h-3Z M5 28 h1 v1 h-1Z M7 28 h1 v1 h-1Z M13 28 h4 v1 h-4Z M21 28 h1 v1 h-1Z M29 28 h3 v1 h-3Z M39 28 h1 v1 h-1Z M45 28 h1 v1 h-1Z M47 28 h1 v1 h-1Z M8 29 h1 v1 h-1Z M11 29 h1 v1 h-1Z M13 29 h1 v1 h-1Z M16 29 h1 v1 h-1Z M18 29 h3 v1 h-3Z M22 29 h1 v1 h-1Z M26 29 h1 v1 h-1Z M28 29 h8 v1 h-8Z M37 29 h1 v1 h-1Z M42 29 h4 v1 h-4Z M47 29 h2 v1 h-2Z M7 30 h3 v1 h-3Z M13 30 h3 v1 h-3Z M18 30 h3 v1 h-3Z M24 30 h2 v1 h-2Z M27 30 h2 v1 h-2Z M30 30 h3 v1 h-3Z M38 30 h1 v1 h-1Z M41 30 h3 v1 h-3Z M5 31 h2 v1 h-2Z M11 31 h1 v1 h-1Z M13 31 h4 v1 h-4Z M20 31 h1 v1 h-1Z M23 31 h6 v1 h-6Z M30 31 h1 v1 h-1Z M33 31 h2 v1 h-2Z M36 31 h2 v1 h-2Z M39 31 h2 v1 h-2Z M42 31 h2 v1 h-2Z M45 31 h1 v1 h-1Z M47 31 h1 v1 h-1Z M5 32 h1 v1 h-1Z M8 32 h2 v1 h-2Z M12 32 h7 v1 h-7Z M20 32 h1 v1 h-1Z M22 32 h4 v1 h-4Z M27 32 h1 v1 h-1Z M32 32 h1 v1 h-1Z M34 32 h4 v1 h-4Z M43 32 h1 v1 h-1Z M8 33 h2 v1 h-2Z M11 33 h4 v1 h-4Z M16 33 h2 v1 h-2Z M22 33 h2 v1 h-2Z M25 33 h1 v1 h-1Z M27 33 h2 v1 h-2Z M31 33 h4 v1 h-4Z M36 33 h3 v1 h-3Z M40 33 h2 v1 h-2Z M43 33 h2 v1 h-2Z M46 33 h1 v1 h-1Z M48 33 h1 v1 h-1Z M4 34 h2 v1 h-2Z M7 34 h3 v1 h-3Z M12 34 h3 v1 h-3Z M18 34 h2 v1 h-2Z M21 34 h1 v1 h-1Z M23 34 h1 v1 h-1Z M27 34 h1 v1 h-1Z M30 34 h3 v1 h-3Z M35 34 h2 v1 h-2Z M40 34 h1 v1 h-1Z M44 34 h5 v1 h-5Z M4 35 h6 v1 h-6Z M11 35 h1 v1 h-1Z M14 35 h1 v1 h-1Z M16 35 h1 v1 h-1Z M18 35 h2 v1 h-2Z M22 35 h1 v1 h-1Z M24 35 h2 v1 h-2Z M28 35 h1 v1 h-1Z M30 35 h1 v1 h-1Z M32 35 h5 v1 h-5Z M38 35 h2 v1 h-2Z M41 35 h4 v1 h-4Z M46 35 h1 v1 h-1Z M48 35 h1 v1 h-1Z M6 36 h4 v1 h-4Z M12 36 h1 v1 h-1Z M16 36 h2 v1 h-2Z M19 36 h1 v1 h-1Z M21 36 h4 v1 h-4Z M28 36 h4 v1 h-4Z M33 36 h2 v1 h-2Z M37 36 h1 v1 h-1Z M39 36 h7 v1 h-7Z M47 36 h2 v1 h-2Z M5 37 h1 v1 h-1Z M7 37 h1 v1 h-1Z M9 37 h1 v1 h-1Z M11 37 h1 v1 h-1Z M13 37 h1 v1 h-1Z M15 37 h1 v1 h-1Z M19 37 h2 v1 h-2Z M23 37 h2 v1 h-2Z M26 37 h2 v1 h-2Z M29 37 h2 v1 h-2Z M33 37 h1 v1 h-1Z M35 37 h1 v1 h-1Z M37 37 h3 v1 h-3Z M42 37 h1 v1 h-1Z M44 37 h1 v1 h-1Z M47 37 h2 v1 h-2Z M13 38 h1 v1 h-1Z M18 38 h1 v1 h-1Z M20 38 h1 v1 h-1Z M26 38 h1 v1 h-1Z M28 38 h7 v1 h-7Z M37 38 h1 v1 h-1Z M39 38 h1 v1 h-1Z M41 38 h5 v1 h-5Z M11 39 h1 v1 h-1Z M15 39 h1 v1 h-1Z M17 39 h2 v1 h-2Z M22 39 h3 v1 h-3Z M27 39 h4 v1 h-4Z M32 39 h3 v1 h-3Z M38 39 h3 v1 h-3Z M42 39 h1 v1 h-1Z M44 39 h1 v1 h-1Z M47 39 h1 v1 h-1Z M13 40 h1 v1 h-1Z M16 40 h1 v1 h-1Z M19 40 h2 v1 h-2Z M22 40 h1 v1 h-1Z M29 40 h3 v1 h-3Z M34 40 h1 v1 h-1Z M36 40 h3 v1 h-3Z M46 40 h1 v1 h-1Z M13 41 h1 v1 h-1Z M15 41 h2 v1 h-2Z M20 41 h4 v1 h-4Z M29 41 h2 v1 h-2Z M38 41 h2 v1 h-2Z M45 41 h1 v1 h-1Z M47 41 h1 v1 h-1Z M13 42 h1 v1 h-1Z M16 42 h2 v1 h-2Z M19 42 h1 v1 h-1Z M22 42 h2 v1 h-2Z M30 42 h3 v1 h-3Z M35 42 h4 v1 h-4Z M46 42 h1 v1 h-1Z M48 42 h1 v1 h-1Z M14 43 h1 v1 h-1Z M18 43 h2 v1 h-2Z M33 43 h3 v1 h-3Z M37 43 h1 v1 h-1Z M47 43 h1 v1 h-1Z M13 44 h4 v1 h-4Z M18 44 h4 v1 h-4Z M29 44 h2 v1 h-2Z M32 44 h2 v1 h-2Z M36 44 h1 v1 h-1Z M45 44 h2 v1 h-2Z M48 44 h1 v1 h-1Z M15 45 h7 v1 h-7Z M24 45 h3 v1 h-3Z M28 45 h1 v1 h-1Z M31 45 h2 v1 h-2Z M34 45 h1 v1 h-1Z M37 45 h1 v1 h-1Z M39 45 h4 v1 h-4Z M44 45 h2 v1 h-2Z M48 45 h1 v1 h-1Z M15 46 h2 v1 h-2Z M21 46 h1 v1 h-1Z M23 46 h1 v1 h-1Z M29 46 h1 v1 h-1Z M31 46 h2 v1 h-2Z M35 46 h1 v1 h-1Z M38 46 h1 v1 h-1Z M43 46 h1 v1 h-1Z M47 46 h2 v1 h-2Z M13 47 h1 v1 h-1Z M16 47 h5 v1 h-5Z M22 47 h2 v1 h-2Z M25 47 h6 v1 h-6Z M32 47 h1 v1 h-1Z M36 47 h1 v1 h-1Z M38 47 h1 v1 h-1Z M40 47 h3 v1 h-3Z M45 47 h1 v1 h-1Z M47 47 h2 v1 h-2Z M13 48 h1 v1 h-1Z M15 48 h5 v1 h-5Z M23 48 h1 v1 h-1Z M25 48 h1 v1 h-1Z M27 48 h2 v1 h-2Z M30 48 h1 v1 h-1Z M32 48 h1 v1 h-1Z M34 48 h5 v1 h-5Z M40 48 h1 v1 h-1Z M43 48 h1 v1 h-1Z M48 48 h1 v1 h-1Z " /><path class="qr-6 " stroke="transparent" fill="#fff" fill-opacity="1" d="M5 5 h5 v1 h-5Z M43 5 h5 v1 h-5Z M5 6 h1 v1 h-1Z M9 6 h1 v1 h-1Z M43 6 h1 v1 h-1Z M47 6 h1 v1 h-1Z M5 7 h1 v1 h-1Z M9 7 h1 v1 h-1Z M43 7 h1 v1 h-1Z M47 7 h1 v1 h-1Z M5 8 h1 v1 h-1Z M9 8 h1 v1 h-1Z M43 8 h1 v1 h-1Z M47 8 h1 v1 h-1Z M5 9 h5 v1 h-5Z M43 9 h5 v1 h-5Z M5 43 h5 v1 h-5Z M5 44 h1 v1 h-1Z M9 44 h1 v1 h-1Z M5 45 h1 v1 h-1Z M9 45 h1 v1 h-1Z M5 46 h1 v1 h-1Z M9 46 h1 v1 h-1Z M5 47 h5 v1 h-5Z " /><path class="qr-8 " stroke="transparent" fill="#fff" fill-opacity="1" d="M11 4 h1 v1 h-1Z M41 4 h1 v1 h-1Z M11 5 h1 v1 h-1Z M41 5 h1 v1 h-1Z M11 6 h1 v1 h-1Z M41 6 h1 v1 h-1Z M11 7 h1 v1 h-1Z M41 7 h1 v1 h-1Z M11 8 h1 v1 h-1Z M41 8 h1 v1 h-1Z M11 9 h1 v1 h-1Z M41 9 h1 v1 h-1Z M11 10 h1 v1 h-1Z M41 10 h1 v1 h-1Z M4 11 h8 v1 h-8Z M41 11 h8 v1 h-8Z M4 41 h8 v1 h-8Z M11 42 h1 v1 h-1Z M11 43 h1 v1 h-1Z M11 44 h1 v1 h-1Z M11 45 h1 v1 h-1Z M11 46 h1 v1 h-1Z M11 47 h1 v1 h-1Z M11 48 h1 v1 h-1Z " /><path class="qr-10 " stroke="transparent" fill="#fff" fill-opacity="1" d="M25 9 h3 v1 h-3Z M25 10 h1 v1 h-1Z M27 10 h1 v1 h-1Z M25 11 h3 v1 h-3Z M9 25 h3 v1 h-3Z M25 25 h3 v1 h-3Z M41 25 h3 v1 h-3Z M9 26 h1 v1 h-1Z M11 26 h1 v1 h-1Z M25 26 h1 v1 h-1Z M27 26 h1 v1 h-1Z M41 26 h1 v1 h-1Z M43 26 h1 v1 h-1Z M9 27 h3 v1 h-3Z M25 27 h3 v1 h-3Z M41 27 h3 v1 h-3Z M25 41 h3 v1 h-3Z M41 41 h3 v1 h-3Z M25 42 h1 v1 h-1Z M27 42 h1 v1 h-1Z M41 42 h1 v1 h-1Z M43 42 h1 v1 h-1Z M25 43 h3 v1 h-3Z M41 43 h3 v1 h-3Z " /><path class="qr-12 " stroke="transparent" fill="#fff" fill-opacity="1" d="M13 10 h1 v1 h-1Z M15 10 h1 v1 h-1Z M17 10 h1 v1 h-1Z M19 10 h1 v1 h-1Z M21 10 h1 v1 h-1Z M23 10 h1 v1 h-1Z M29 10 h1 v1 h-1Z M31 10 h1 v1 h-1Z M33 10 h1 v1 h-1Z M35 10 h1 v1 h-1Z M37 10 h1 v1 h-1Z M39 10 h1 v1 h-1Z M10 13 h1 v1 h-1Z M10 15 h1 v1 h-1Z M10 17 h1 v1 h-1Z M10 19 h1 v1 h-1Z M10 21 h1 v1 h-1Z M10 23 h1 v1 h-1Z M10 29 h1 v1 h-1Z M10 31 h1 v1 h-1Z M10 33 h1 v1 h-1Z M10 35 h1 v1 h-1Z M10 37 h1 v1 h-1Z M10 39 h1 v1 h-1Z " /><path class="qr-14 " stroke="transparent" fill="#fff" fill-opacity="1" d="M12 7 h1 v1 h-1Z M12 8 h1 v1 h-1Z M4 12 h2 v1 h-2Z M9 12 h1 v1 h-1Z M11 12 h1 v1 h-1Z M44 12 h2 v1 h-2Z M12 42 h1 v1 h-1Z M12 43 h1 v1 h-1Z M12 47 h1 v1 h-1Z M12 48 h1 v1 h-1Z " /><path class="qr-16 " stroke="transparent" fill="#fff" fill-opacity="1" d="M38 4 h2 v1 h-2Z M38 5 h1 v1 h-1Z M40 5 h1 v1 h-1Z M38 6 h1 v1 h-1Z M40 6 h1 v1 h-1Z M38 7 h1 v1 h-1Z M38 9 h3 v1 h-3Z M4 38 h4 v1 h-4Z M9 38 h1 v1 h-1Z M4 39 h1 v1 h-1Z M9 39 h1 v1 h-1Z M5 40 h2 v1 h-2Z M9 40 h1 v1 h-1Z " /><path class="qr-18 " stroke="transparent" fill="#fff" fill-opacity="1" d="M0 0 h53 v1 h-53Z M0 1 h53 v1 h-53Z M0 2 h53 v1 h-53Z M0 3 h53 v1 h-53Z M0 4 h4 v1 h-4Z M49 4 h4 v1 h-4Z M0 5 h4 v1 h-4Z M49 5 h4 v1 h-4Z M0 6 h4 v1 h-4Z M49 6 h4 v1 h-4Z M0 7 h4 v1 h-4Z M49 7 h4 v1 h-4Z M0 8 h4 v1 h-4Z M49 8 h4 v1 h-4Z M0 9 h4 v1 h-4Z M49 9 h4 v1 h-4Z M0 10 h4 v1 h-4Z M49 10 h4 v1 h-4Z M0 11 h4 v1 h-4Z M49 11 h4 v1 h-4Z M0 12 h4 v1 h-4Z M49 12 h4 v1 h-4Z M0 13 h4 v1 h-4Z M49 13 h4 v1 h-4Z M0 14 h4 v1 h-4Z M49 14 h4 v1 h-4Z M0 15 h4 v1 h-4Z M49 15 h4 v1 h-4Z M0 16 h4 v1 h-4Z M49 16 h4 v1 h-4Z M0 17 h4 v1 h-4Z M49 17 h4 v1 h-4Z M0 18 h4 v1 h-4Z M49 18 h4 v1 h-4Z M0 19 h4 v1 h-4Z M49 19 h4 v1 h-4Z M0 20 h4 v1 h-4Z M49 20 h4 v1 h-4Z M0 21 h4 v1 h-4Z M49 21 h4 v1 h-4Z M0 22 h4 v1 h-4Z M49 22 h4 v1 h-4Z M0 23 h4 v1 h-4Z M49 23 h4 v1 h-4Z M0 24 h4 v1 h-4Z M49 24 h4 v1 h-4Z M0 25 h4 v1 h-4Z M49 25 h4 v1 h-4Z M0 26 h4 v1 h-4Z M49 26 h4 v1 h-4Z M0 27 h4 v1 h-4Z M49 27 h4 v1 h-4Z M0 28 h4 v1 h-4Z M49 28 h4 v1 h-4Z M0 29 h4 v1 h-4Z M49 29 h4 v1 h-4Z M0 30 h4 v1 h-4Z M49 30 h4 v1 h-4Z M0 31 h4 v1 h-4Z M49 31 h4 v1 h-4Z M0 32 h4 v1 h-4Z M49 32 h4 v1 h-4Z M0 33 h4 v1 h-4Z M49 33 h4 v1 h-4Z M0 34 h4 v1 h-4Z M49 34 h4 v1 h-4Z M0 35 h4 v1 h-4Z M49 35 h4 v1 h-4Z M0 36 h4 v1 h-4Z M49 36 h4 v1 h-4Z M0 37 h4 v1 h-4Z M49 37 h4 v1 h-4Z M0 38 h4 v1 h-4Z M49 38 h4 v1 h-4Z M0 39 h4 v1 h-4Z M49 39 h4 v1 h-4Z M0 40 h4 v1 h-4Z M49 40 h4 v1 h-4Z M0 41 h4 v1 h-4Z M49 41 h4 v1 h-4Z M0 42 h4 v1 h-4Z M49 42 h4 v1 h-4Z M0 43 h4 v1 h-4Z M49 43 h4 v1 h-4Z M0 44 h4 v1 h-4Z M49 44 h4 v1 h-4Z M0 45 h4 v1 h-4Z M49 45 h4 v1 h-4Z M0 46 h4 v1 h-4Z M49 46 h4 v1 h-4Z M0 47 h4 v1 h-4Z M49 47 h4 v1 h-4Z M0 48 h4 v1 h-4Z M49 48 h4 v1 h-4Z M0 49 h53 v1 h-53Z M0 50 h53 v1 h-53Z M0 51 h53 v1 h-53Z M0 52 h53 v1 h-53Z " /><path class="qr-512 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 41 h1 v1 h-1Z " /><path class="qr-1024 " stroke="transparent" fill="#000" fill-opacity="1" d="M13 4 h3 v1 h-3Z M18 4 h1 v1 h-1Z M20 4 h4 v1 h-4Z M25 4 h3 v1 h-3Z M29 4 h1 v1 h-1Z M32 4 h4 v1 h-4Z M37 4 h1 v1 h-1Z M17 5 h3 v1 h-3Z M22 5 h1 v1 h-1Z M24 5 h1 v1 h-1Z M27 5 h2 v1 h-2Z M30 5 h1 v1 h-1Z M35 5 h2 v1 h-2Z M13 6 h1 v1 h-1Z M17 6 h2 v1 h-2Z M20 6 h1 v1 h-1Z M23 6 h1 v1 h-1Z M27 6 h2 v1 h-2Z M33 6 h3 v1 h-3Z M37 6 h1 v1 h-1Z M16 7 h1 v1 h-1Z M20 7 h1 v1 h-1Z M25 7 h1 v1 h-1Z M29 7 h1 v1 h-1Z M31 7 h1 v1 h-1Z M33 7 h2 v1 h-2Z M37 7 h1 v1 h-1Z M14 8 h5 v1 h-5Z M20 8 h1 v1 h-1Z M23 8 h1 v1 h-1Z M34 8 h2 v1 h-2Z M37 8 h1 v1 h-1Z M13 9 h1 v1 h-1Z M15 9 h2 v1 h-2Z M21 9 h1 v1 h-1Z M23 9 h1 v1 h-1Z M30 9 h3 v1 h-3Z M34 9 h1 v1 h-1Z M13 11 h1 v1 h-1Z M17 11 h3 v1 h-3Z M29 11 h2 v1 h-2Z M32 11 h2 v1 h-2Z M38 11 h1 v1 h-1Z M40 11 h1 v1 h-1Z M13 12 h1 v1 h-1Z M15 12 h2 v1 h-2Z M20 12 h4 v1 h-4Z M29 12 h4 v1 h-4Z M35 12 h2 v1 h-2Z M38 12 h1 v1 h-1Z M40 12 h1 v1 h-1Z M4 13 h1 v1 h-1Z M8 13 h2 v1 h-2Z M12 13 h1 v1 h-1Z M16 13 h4 v1 h-4Z M24 13 h1 v1 h-1Z M26 13 h4 v1 h-4Z M33 13 h1 v1 h-1Z M36 13 h2 v1 h-2Z M39 13 h1 v1 h-1Z M41 13 h4 v1 h-4Z M46 13 h1 v1 h-1Z M6 14 h2 v1 h-2Z M11 14 h2 v1 h-2Z M17 14 h1 v1 h-1Z M20 14 h6 v1 h-6Z M28 14 h5 v1 h-5Z M34 14 h5 v1 h-5Z M44 14 h5 v1 h-5Z M6 15 h1 v1 h-1Z M8 15 h2 v1 h-2Z M11 15 h1 v1 h-1Z M16 15 h5 v1 h-5Z M23 15 h1 v1 h-1Z M26 15 h2 v1 h-2Z M30 15 h3 v1 h-3Z M34 15 h2 v1 h-2Z M39 15 h1 v1 h-1Z M46 15 h1 v1 h-1Z M48 15 h1 v1 h-1Z M4 16 h2 v1 h-2Z M7 16 h1 v1 h-1Z M9 16 h1 v1 h-1Z M11 16 h1 v1 h-1Z M13 16 h3 v1 h-3Z M18 16 h4 v1 h-4Z M27 16 h8 v1 h-8Z M39 16 h2 v1 h-2Z M43 16 h1 v1 h-1Z M45 16 h4 v1 h-4Z M4 17 h1 v1 h-1Z M9 17 h1 v1 h-1Z M11 17 h1 v1 h-1Z M13 17 h4 v1 h-4Z M18 17 h1 v1 h-1Z M21 17 h1 v1 h-1Z M23 17 h2 v1 h-2Z M26 17 h2 v1 h-2Z M29 17 h1 v1 h-1Z M31 17 h1 v1 h-1Z M34 17 h2 v1 h-2Z M40 17 h2 v1 h-2Z M47 17 h1 v1 h-1Z M5 18 h3 v1 h-3Z M11 18 h1 v1 h-1Z M17 18 h2 v1 h-2Z M21 18 h1 v1 h-1Z M27 18 h1 v1 h-1Z M29 18 h2 v1 h-2Z M32 18 h3 v1 h-3Z M37 18 h7 v1 h-7Z M46 18 h1 v1 h-1Z M4 19 h1 v1 h-1Z M6 19 h2 v1 h-2Z M12 19 h1 v1 h-1Z M14 19 h2 v1 h-2Z M20 19 h2 v1 h-2Z M25 19 h3 v1 h-3Z M29 19 h5 v1 h-5Z M36 19 h1 v1 h-1Z M38 19 h1 v1 h-1Z M40 19 h4 v1 h-4Z M45 19 h3 v1 h-3Z M7 20 h3 v1 h-3Z M13 20 h6 v1 h-6Z M22 20 h1 v1 h-1Z M27 20 h3 v1 h-3Z M35 20 h1 v1 h-1Z M37 20 h3 v1 h-3Z M41 20 h1 v1 h-1Z M44 20 h2 v1 h-2Z M6 21 h2 v1 h-2Z M13 21 h1 v1 h-1Z M15 21 h1 v1 h-1Z M17 21 h2 v1 h-2Z M20 21 h3 v1 h-3Z M24 21 h3 v1 h-3Z M30 21 h2 v1 h-2Z M33 21 h1 v1 h-1Z M38 21 h3 v1 h-3Z M43 21 h3 v1 h-3Z M48 21 h1 v1 h-1Z M4 22 h2 v1 h-2Z M8 22 h1 v1 h-1Z M11 22 h1 v1 h-1Z M13 22 h1 v1 h-1Z M18 22 h2 v1 h-2Z M22 22 h3 v1 h-3Z M27 22 h2 v1 h-2Z M30 22 h3 v1 h-3Z M34 22 h2 v1 h-2Z M37 22 h1 v1 h-1Z M40 22 h1 v1 h-1Z M42 22 h1 v1 h-1Z M44 22 h1 v1 h-1Z M5 23 h1 v1 h-1Z M8 23 h1 v1 h-1Z M13 23 h1 v1 h-1Z M15 23 h1 v1 h-1Z M17 23 h3 v1 h-3Z M23 23 h1 v1 h-1Z M28 23 h1 v1 h-1Z M32 23 h1 v1 h-1Z M34 23 h1 v1 h-1Z M36 23 h2 v1 h-2Z M43 23 h5 v1 h-5Z M6 24 h2 v1 h-2Z M15 24 h3 v1 h-3Z M19 24 h1 v1 h-1Z M21 24 h3 v1 h-3Z M29 24 h6 v1 h-6Z M48 24 h1 v1 h-1Z M13 25 h4 v1 h-4Z M19 25 h1 v1 h-1Z M21 25 h1 v1 h-1Z M23 25 h1 v1 h-1Z M29 25 h4 v1 h-4Z M34 25 h4 v1 h-4Z M39 25 h1 v1 h-1Z M45 25 h1 v1 h-1Z M48 25 h1 v1 h-1Z M4 26 h2 v1 h-2Z M13 26 h1 v1 h-1Z M15 26 h5 v1 h-5Z M21 26 h3 v1 h-3Z M30 26 h7 v1 h-7Z M47 26 h1 v1 h-1Z M4 27 h1 v1 h-1Z M6 27 h2 v1 h-2Z M13 27 h1 v1 h-1Z M23 27 h1 v1 h-1Z M29 27 h1 v1 h-1Z M31 27 h2 v1 h-2Z M34 27 h1 v1 h-1Z M38 27 h1 v1 h-1Z M45 27 h1 v1 h-1Z M4 28 h1 v1 h-1Z M6 28 h1 v1 h-1Z M17 28 h4 v1 h-4Z M22 28 h2 v1 h-2Z M32 28 h7 v1 h-7Z M46 28 h1 v1 h-1Z M48 28 h1 v1 h-1Z M4 29 h4 v1 h-4Z M9 29 h1 v1 h-1Z M12 29 h1 v1 h-1Z M14 29 h2 v1 h-2Z M17 29 h1 v1 h-1Z M21 29 h1 v1 h-1Z M23 29 h3 v1 h-3Z M27 29 h1 v1 h-1Z M36 29 h1 v1 h-1Z M38 29 h4 v1 h-4Z M46 29 h1 v1 h-1Z M4 30 h3 v1 h-3Z M11 30 h2 v1 h-2Z M16 30 h2 v1 h-2Z M21 30 h3 v1 h-3Z M26 30 h1 v1 h-1Z M29 30 h1 v1 h-1Z M33 30 h5 v1 h-5Z M39 30 h2 v1 h-2Z M44 30 h5 v1 h-5Z M4 31 h1 v1 h-1Z M7 31 h3 v1 h-3Z M12 31 h1 v1 h-1Z M17 31 h3 v1 h-3Z M21 31 h2 v1 h-2Z M29 31 h1 v1 h-1Z M31 31 h2 v1 h-2Z M35 31 h1 v1 h-1Z M38 31 h1 v1 h-1Z M41 31 h1 v1 h-1Z M44 31 h1 v1 h-1Z M46 31 h1 v1 h-1Z M48 31 h1 v1 h-1Z M4 32 h1 v1 h-1Z M6 32 h2 v1 h-2Z M11 32 h1 v1 h-1Z M19 32 h1 v1 h-1Z M21 32 h1 v1 h-1Z M26 32 h1 v1 h-1Z M28 32 h4 v1 h-4Z M33 32 h1 v1 h-1Z M38 32 h5 v1 h-5Z M44 32 h5 v1 h-5Z M4 33 h4 v1 h-4Z M15 33 h1 v1 h-1Z M18 33 h4 v1 h-4Z M24 33 h1 v1 h-1Z M26 33 h1 v1 h-1Z M29 33 h2 v1 h-2Z M35 33 h1 v1 h-1Z M39 33 h1 v1 h-1Z M42 33 h1 v1 h-1Z M45 33 h1 v1 h-1Z M47 33 h1 v1 h-1Z M6 34 h1 v1 h-1Z M11 34 h1 v1 h-1Z M15 34 h3 v1 h-3Z M20 34 h1 v1 h-1Z M22 34 h1 v1 h-1Z M24 34 h3 v1 h-3Z M28 34 h2 v1 h-2Z M33 34 h2 v1 h-2Z M37 34 h3 v1 h-3Z M41 34 h3 v1 h-3Z M12 35 h2 v1 h-2Z M15 35 h1 v1 h-1Z M17 35 h1 v1 h-1Z M20 35 h2 v1 h-2Z M23 35 h1 v1 h-1Z M26 35 h2 v1 h-2Z M29 35 h1 v1 h-1Z M31 35 h1 v1 h-1Z M37 35 h1 v1 h-1Z M40 35 h1 v1 h-1Z M45 35 h1 v1 h-1Z M47 35 h1 v1 h-1Z M4 36 h2 v1 h-2Z M11 36 h1 v1 h-1Z M13 36 h3 v1 h-3Z M18 36 h1 v1 h-1Z M20 36 h1 v1 h-1Z M25 36 h3 v1 h-3Z M32 36 h1 v1 h-1Z M35 36 h2 v1 h-2Z M38 36 h1 v1 h-1Z M46 36 h1 v1 h-1Z M4 37 h1 v1 h-1Z M6 37 h1 v1 h-1Z M8 37 h1 v1 h-1Z M12 37 h1 v1 h-1Z M14 37 h1 v1 h-1Z M16 37 h3 v1 h-3Z M21 37 h2 v1 h-2Z M25 37 h1 v1 h-1Z M28 37 h1 v1 h-1Z M31 37 h2 v1 h-2Z M34 37 h1 v1 h-1Z M36 37 h1 v1 h-1Z M40 37 h2 v1 h-2Z M43 37 h1 v1 h-1Z M45 37 h2 v1 h-2Z M11 38 h2 v1 h-2Z M14 38 h4 v1 h-4Z M19 38 h1 v1 h-1Z M21 38 h5 v1 h-5Z M27 38 h1 v1 h-1Z M35 38 h2 v1 h-2Z M38 38 h1 v1 h-1Z M40 38 h1 v1 h-1Z M46 38 h3 v1 h-3Z M12 39 h3 v1 h-3Z M16 39 h1 v1 h-1Z M19 39 h3 v1 h-3Z M25 39 h2 v1 h-2Z M31 39 h1 v1 h-1Z M35 39 h3 v1 h-3Z M41 39 h1 v1 h-1Z M43 39 h1 v1 h-1Z M45 39 h2 v1 h-2Z M48 39 h1 v1 h-1Z M11 40 h2 v1 h-2Z M14 40 h2 v1 h-2Z M17 40 h2 v1 h-2Z M21 40 h1 v1 h-1Z M23 40 h1 v1 h-1Z M32 40 h2 v1 h-2Z M35 40 h1 v1 h-1Z M39 40 h1 v1 h-1Z M45 40 h1 v1 h-1Z M47 40 h2 v1 h-2Z M14 41 h1 v1 h-1Z M17 41 h3 v1 h-3Z M31 41 h7 v1 h-7Z M46 41 h1 v1 h-1Z M48 41 h1 v1 h-1Z M14 42 h2 v1 h-2Z M18 42 h1 v1 h-1Z M20 42 h2 v1 h-2Z M29 42 h1 v1 h-1Z M33 42 h2 v1 h-2Z M39 42 h1 v1 h-1Z M45 42 h1 v1 h-1Z M47 42 h1 v1 h-1Z M13 43 h1 v1 h-1Z M15 43 h3 v1 h-3Z M20 43 h4 v1 h-4Z M29 43 h4 v1 h-4Z M36 43 h1 v1 h-1Z M38 43 h2 v1 h-2Z M45 43 h2 v1 h-2Z M48 43 h1 v1 h-1Z M17 44 h1 v1 h-1Z M22 44 h2 v1 h-2Z M31 44 h1 v1 h-1Z M34 44 h2 v1 h-2Z M37 44 h3 v1 h-3Z M47 44 h1 v1 h-1Z M13 45 h2 v1 h-2Z M22 45 h2 v1 h-2Z M27 45 h1 v1 h-1Z M29 45 h2 v1 h-2Z M33 45 h1 v1 h-1Z M35 45 h2 v1 h-2Z M38 45 h1 v1 h-1Z M43 45 h1 v1 h-1Z M46 45 h2 v1 h-2Z M13 46 h2 v1 h-2Z M17 46 h4 v1 h-4Z M22 46 h1 v1 h-1Z M24 46 h5 v1 h-5Z M30 46 h1 v1 h-1Z M33 46 h2 v1 h-2Z M36 46 h2 v1 h-2Z M39 46 h4 v1 h-4Z M44 46 h3 v1 h-3Z M14 47 h2 v1 h-2Z M21 47 h1 v1 h-1Z M24 47 h1 v1 h-1Z M31 47 h1 v1 h-1Z M33 47 h3 v1 h-3Z M37 47 h1 v1 h-1Z M39 47 h1 v1 h-1Z M43 47 h2 v1 h-2Z M46 47 h1 v1 h-1Z M14 48 h1 v1 h-1Z M20 48 h3 v1 h-3Z M24 48 h1 v1 h-1Z M26 48 h1 v1 h-1Z M29 48 h1 v1 h-1Z M31 48 h1 v1 h-1Z M33 48 h1 v1 h-1Z M39 48 h1 v1 h-1Z M41 48 h2 v1 h-2Z M44 48 h4 v1 h-4Z " /><path class="qr-1536 " stroke="transparent" fill="#000" fill-opacity="1" d="M4 4 h7 v1 h-7Z M42 4 h7 v1 h-7Z M4 5 h1 v1 h-1Z M10 5 h1 v1 h-1Z M42 5 h1 v1 h-1Z M48 5 h1 v1 h-1Z M4 6 h1 v1 h-1Z M10 6 h1 v1 h-1Z M42 6 h1 v1 h-1Z M48 6 h1 v1 h-1Z M4 7 h1 v1 h-1Z M10 7 h1 v1 h-1Z M42 7 h1 v1 h-1Z M48 7 h1 v1 h-1Z M4 8 h1 v1 h-1Z M10 8 h1 v1 h-1Z M42 8 h1 v1 h-1Z M48 8 h1 v1 h-1Z M4 9 h1 v1 h-1Z M10 9 h1 v1 h-1Z M42 9 h1 v1 h-1Z M48 9 h1 v1 h-1Z M4 10 h7 v1 h-7Z M42 10 h7 v1 h-7Z M4 42 h7 v1 h-7Z M4 43 h1 v1 h-1Z M10 43 h1 v1 h-1Z M4 44 h1 v1 h-1Z M10 44 h1 v1 h-1Z M4 45 h1 v1 h-1Z M10 45 h1 v1 h-1Z M4 46 h1 v1 h-1Z M10 46 h1 v1 h-1Z M4 47 h1 v1 h-1Z M10 47 h1 v1 h-1Z M4 48 h7 v1 h-7Z " /><path class="qr-2560 " stroke="transparent" fill="#000" fill-opacity="1" d="M24 8 h5 v1 h-5Z M24 9 h1 v1 h-1Z M28 9 h1 v1 h-1Z M24 10 h1 v1 h-1Z M26 10 h1 v1 h-1Z M28 10 h1 v1 h-1Z M24 11 h1 v1 h-1Z M28 11 h1 v1 h-1Z M24 12 h5 v1 h-5Z M8 24 h5 v1 h-5Z M24 24 h5 v1 h-5Z M40 24 h5 v1 h-5Z M8 25 h1 v1 h-1Z M12 25 h1 v1 h-1Z M24 25 h1 v1 h-1Z M28 25 h1 v1 h-1Z M40 25 h1 v1 h-1Z M44 25 h1 v1 h-1Z M8 26 h1 v1 h-1Z M10 26 h1 v1 h-1Z M12 26 h1 v1 h-1Z M24 26 h1 v1 h-1Z M26 26 h1 v1 h-1Z M28 26 h1 v1 h-1Z M40 26 h1 v1 h-1Z M42 26 h1 v1 h-1Z M44 26 h1 v1 h-1Z M8 27 h1 v1 h-1Z M12 27 h1 v1 h-1Z M24 27 h1 v1 h-1Z M28 27 h1 v1 h-1Z M40 27 h1 v1 h-1Z M44 27 h1 v1 h-1Z M8 28 h5 v1 h-5Z M24 28 h5 v1 h-5Z M40 28 h5 v1 h-5Z M24 40 h5 v1 h-5Z M40 40 h5 v1 h-5Z M24 41 h1 v1 h-1Z M28 41 h1 v1 h-1Z M40 41 h1 v1 h-1Z M44 41 h1 v1 h-1Z M24 42 h1 v1 h-1Z M26 42 h1 v1 h-1Z M28 42 h1 v1 h-1Z M40 42 h1 v1 h-1Z M42 42 h1 v1 h-1Z M44 42 h1 v1 h-1Z M24 43 h1 v1 h-1Z M28 43 h1 v1 h-1Z M40 43 h1 v1 h-1Z M44 43 h1 v1 h-1Z M24 44 h5 v1 h-5Z M40 44 h5 v1 h-5Z " /><path class="qr-3072 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 10 h1 v1 h-1Z M14 10 h1 v1 h-1Z M16 10 h1 v1 h-1Z M18 10 h1 v1 h-1Z M20 10 h1 v1 h-1Z M22 10 h1 v1 h-1Z M30 10 h1 v1 h-1Z M32 10 h1 v1 h-1Z M34 10 h1 v1 h-1Z M36 10 h1 v1 h-1Z M38 10 h1 v1 h-1Z M40 10 h1 v1 h-1Z M10 12 h1 v1 h-1Z M10 14 h1 v1 h-1Z M10 16 h1 v1 h-1Z M10 18 h1 v1 h-1Z M10 20 h1 v1 h-1Z M10 22 h1 v1 h-1Z M10 30 h1 v1 h-1Z M10 32 h1 v1 h-1Z M10 34 h1 v1 h-1Z M10 36 h1 v1 h-1Z M10 38 h1 v1 h-1Z M10 40 h1 v1 h-1Z " /><path class="qr-3584 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 4 h1 v1 h-1Z M12 5 h1 v1 h-1Z M12 6 h1 v1 h-1Z M12 9 h1 v1 h-1Z M12 11 h1 v1 h-1Z M6 12 h3 v1 h-3Z M12 12 h1 v1 h-1Z M41 12 h3 v1 h-3Z M46 12 h3 v1 h-3Z M12 44 h1 v1 h-1Z M12 45 h1 v1 h-1Z M12 46 h1 v1 h-1Z " /><path class="qr-4096 " stroke="transparent" fill="#000" fill-opacity="1" d="M40 4 h1 v1 h-1Z M39 5 h1 v1 h-1Z M39 6 h1 v1 h-1Z M39 7 h2 v1 h-2Z M38 8 h3 v1 h-3Z M8 38 h1 v1 h-1Z M5 39 h4 v1 h-4Z M4 40 h1 v1 h-1Z M7 40 h2 v1 h-2Z " /><path class="qr-5632 " stroke="transparent" fill="#000" fill-opacity="1" d="M6 6 h3 v1 h-3Z M44 6 h3 v1 h-3Z M6 7 h3 v1 h-3Z M44 7 h3 v1 h-3Z M6 8 h3 v1 h-3Z M44 8 h3 v1 h-3Z M6 44 h3 v1 h-3Z M6 45 h3 v1 h-3Z M6 46 h3 v1 h-3Z " /></svg>

    </a>
    <figcaption aria-hidden="true" class="hidden" hidden>Et, un Ko-fi pour Stéphane HUC</figcaption>
</figure>


<h3 id="liberapay">Liberapay</h3>
<ul>
<li><a href="https://fr.liberapay.com/HucSte/donate" rel="external">https://fr.liberapay.com/HucSte/donate</a></li>
</ul>


<figure class="pure-img">
    <a href="/svg/qrcode/liberapay.svg" title="Un don Liberapay pour Stéphane HUC">
    <svg xmlns="http://www.w3.org/2000/svg" class="qr-svg " height="128" viewBox="0 0 53 53" width="128">
<defs><style>rect{shape-rendering:crispEdges}</style></defs>
<path class="qr-4 " stroke="transparent" fill="#fff" fill-opacity="1" d="M14 4 h2 v1 h-2Z M18 4 h1 v1 h-1Z M22 4 h5 v1 h-5Z M28 4 h1 v1 h-1Z M30 4 h2 v1 h-2Z M35 4 h1 v1 h-1Z M13 5 h1 v1 h-1Z M15 5 h2 v1 h-2Z M18 5 h1 v1 h-1Z M20 5 h1 v1 h-1Z M23 5 h1 v1 h-1Z M26 5 h3 v1 h-3Z M30 5 h2 v1 h-2Z M36 5 h1 v1 h-1Z M17 6 h1 v1 h-1Z M26 6 h1 v1 h-1Z M28 6 h2 v1 h-2Z M31 6 h2 v1 h-2Z M35 6 h3 v1 h-3Z M13 7 h3 v1 h-3Z M17 7 h3 v1 h-3Z M21 7 h8 v1 h-8Z M30 7 h1 v1 h-1Z M35 7 h2 v1 h-2Z M13 8 h1 v1 h-1Z M15 8 h2 v1 h-2Z M18 8 h3 v1 h-3Z M22 8 h2 v1 h-2Z M29 8 h2 v1 h-2Z M32 8 h1 v1 h-1Z M34 8 h1 v1 h-1Z M37 8 h1 v1 h-1Z M13 9 h1 v1 h-1Z M16 9 h2 v1 h-2Z M20 9 h1 v1 h-1Z M23 9 h1 v1 h-1Z M29 9 h1 v1 h-1Z M33 9 h1 v1 h-1Z M36 9 h1 v1 h-1Z M13 11 h1 v1 h-1Z M20 11 h4 v1 h-4Z M29 11 h1 v1 h-1Z M33 11 h3 v1 h-3Z M40 11 h1 v1 h-1Z M13 12 h1 v1 h-1Z M15 12 h4 v1 h-4Z M20 12 h1 v1 h-1Z M22 12 h2 v1 h-2Z M29 12 h1 v1 h-1Z M31 12 h5 v1 h-5Z M38 12 h3 v1 h-3Z M4 13 h3 v1 h-3Z M9 13 h1 v1 h-1Z M11 13 h2 v1 h-2Z M14 13 h2 v1 h-2Z M18 13 h2 v1 h-2Z M21 13 h1 v1 h-1Z M23 13 h1 v1 h-1Z M25 13 h1 v1 h-1Z M27 13 h3 v1 h-3Z M31 13 h2 v1 h-2Z M35 13 h1 v1 h-1Z M38 13 h1 v1 h-1Z M40 13 h1 v1 h-1Z M45 13 h1 v1 h-1Z M47 13 h2 v1 h-2Z M5 14 h4 v1 h-4Z M11 14 h1 v1 h-1Z M13 14 h4 v1 h-4Z M19 14 h1 v1 h-1Z M21 14 h2 v1 h-2Z M24 14 h1 v1 h-1Z M26 14 h1 v1 h-1Z M29 14 h1 v1 h-1Z M31 14 h1 v1 h-1Z M36 14 h2 v1 h-2Z M41 14 h1 v1 h-1Z M45 14 h2 v1 h-2Z M48 14 h1 v1 h-1Z M7 15 h1 v1 h-1Z M9 15 h1 v1 h-1Z M12 15 h2 v1 h-2Z M16 15 h4 v1 h-4Z M21 15 h1 v1 h-1Z M23 15 h3 v1 h-3Z M27 15 h2 v1 h-2Z M31 15 h5 v1 h-5Z M37 15 h2 v1 h-2Z M42 15 h1 v1 h-1Z M45 15 h2 v1 h-2Z M7 16 h1 v1 h-1Z M11 16 h3 v1 h-3Z M17 16 h1 v1 h-1Z M19 16 h1 v1 h-1Z M22 16 h3 v1 h-3Z M26 16 h2 v1 h-2Z M31 16 h2 v1 h-2Z M36 16 h7 v1 h-7Z M44 16 h1 v1 h-1Z M4 17 h3 v1 h-3Z M8 17 h1 v1 h-1Z M11 17 h1 v1 h-1Z M13 17 h1 v1 h-1Z M15 17 h2 v1 h-2Z M18 17 h4 v1 h-4Z M24 17 h4 v1 h-4Z M31 17 h2 v1 h-2Z M34 17 h1 v1 h-1Z M37 17 h4 v1 h-4Z M44 17 h1 v1 h-1Z M48 17 h1 v1 h-1Z M4 18 h2 v1 h-2Z M8 18 h2 v1 h-2Z M11 18 h1 v1 h-1Z M16 18 h2 v1 h-2Z M19 18 h3 v1 h-3Z M23 18 h3 v1 h-3Z M27 18 h3 v1 h-3Z M31 18 h1 v1 h-1Z M34 18 h1 v1 h-1Z M36 18 h3 v1 h-3Z M41 18 h1 v1 h-1Z M43 18 h1 v1 h-1Z M45 18 h4 v1 h-4Z M8 19 h2 v1 h-2Z M11 19 h1 v1 h-1Z M13 19 h1 v1 h-1Z M15 19 h1 v1 h-1Z M17 19 h1 v1 h-1Z M19 19 h1 v1 h-1Z M21 19 h1 v1 h-1Z M24 19 h1 v1 h-1Z M32 19 h1 v1 h-1Z M34 19 h2 v1 h-2Z M37 19 h2 v1 h-2Z M40 19 h4 v1 h-4Z M47 19 h2 v1 h-2Z M5 20 h2 v1 h-2Z M9 20 h1 v1 h-1Z M12 20 h2 v1 h-2Z M16 20 h2 v1 h-2Z M20 20 h1 v1 h-1Z M24 20 h2 v1 h-2Z M27 20 h4 v1 h-4Z M37 20 h3 v1 h-3Z M44 20 h2 v1 h-2Z M47 20 h2 v1 h-2Z M4 21 h1 v1 h-1Z M6 21 h2 v1 h-2Z M9 21 h1 v1 h-1Z M13 21 h1 v1 h-1Z M18 21 h1 v1 h-1Z M20 21 h1 v1 h-1Z M23 21 h1 v1 h-1Z M25 21 h1 v1 h-1Z M27 21 h3 v1 h-3Z M31 21 h1 v1 h-1Z M35 21 h1 v1 h-1Z M40 21 h3 v1 h-3Z M44 21 h3 v1 h-3Z M4 22 h1 v1 h-1Z M7 22 h1 v1 h-1Z M9 22 h1 v1 h-1Z M11 22 h8 v1 h-8Z M20 22 h1 v1 h-1Z M22 22 h1 v1 h-1Z M24 22 h2 v1 h-2Z M32 22 h2 v1 h-2Z M44 22 h3 v1 h-3Z M48 22 h1 v1 h-1Z M8 23 h2 v1 h-2Z M11 23 h1 v1 h-1Z M14 23 h2 v1 h-2Z M18 23 h4 v1 h-4Z M23 23 h2 v1 h-2Z M26 23 h1 v1 h-1Z M28 23 h5 v1 h-5Z M34 23 h5 v1 h-5Z M40 23 h1 v1 h-1Z M43 23 h1 v1 h-1Z M45 23 h2 v1 h-2Z M5 24 h2 v1 h-2Z M16 24 h3 v1 h-3Z M20 24 h1 v1 h-1Z M22 24 h2 v1 h-2Z M29 24 h1 v1 h-1Z M31 24 h1 v1 h-1Z M34 24 h1 v1 h-1Z M36 24 h1 v1 h-1Z M39 24 h1 v1 h-1Z M45 24 h1 v1 h-1Z M4 25 h2 v1 h-2Z M7 25 h1 v1 h-1Z M13 25 h7 v1 h-7Z M21 25 h3 v1 h-3Z M29 25 h2 v1 h-2Z M33 25 h1 v1 h-1Z M35 25 h1 v1 h-1Z M38 25 h1 v1 h-1Z M47 25 h1 v1 h-1Z M4 26 h1 v1 h-1Z M13 26 h4 v1 h-4Z M18 26 h1 v1 h-1Z M20 26 h1 v1 h-1Z M23 26 h1 v1 h-1Z M30 26 h2 v1 h-2Z M33 26 h3 v1 h-3Z M38 26 h1 v1 h-1Z M45 26 h2 v1 h-2Z M6 27 h1 v1 h-1Z M13 27 h1 v1 h-1Z M15 27 h1 v1 h-1Z M18 27 h1 v1 h-1Z M21 27 h2 v1 h-2Z M30 27 h1 v1 h-1Z M33 27 h2 v1 h-2Z M36 27 h1 v1 h-1Z M38 27 h2 v1 h-2Z M46 27 h1 v1 h-1Z M4 28 h1 v1 h-1Z M7 28 h1 v1 h-1Z M15 28 h2 v1 h-2Z M20 28 h1 v1 h-1Z M23 28 h1 v1 h-1Z M30 28 h1 v1 h-1Z M32 28 h3 v1 h-3Z M39 28 h1 v1 h-1Z M45 28 h2 v1 h-2Z M48 28 h1 v1 h-1Z M5 29 h4 v1 h-4Z M11 29 h5 v1 h-5Z M19 29 h2 v1 h-2Z M23 29 h1 v1 h-1Z M25 29 h1 v1 h-1Z M28 29 h3 v1 h-3Z M32 29 h2 v1 h-2Z M35 29 h2 v1 h-2Z M39 29 h3 v1 h-3Z M44 29 h1 v1 h-1Z M46 29 h2 v1 h-2Z M9 30 h1 v1 h-1Z M11 30 h1 v1 h-1Z M13 30 h1 v1 h-1Z M15 30 h3 v1 h-3Z M23 30 h2 v1 h-2Z M26 30 h3 v1 h-3Z M30 30 h1 v1 h-1Z M32 30 h1 v1 h-1Z M35 30 h1 v1 h-1Z M37 30 h1 v1 h-1Z M40 30 h5 v1 h-5Z M46 30 h2 v1 h-2Z M5 31 h2 v1 h-2Z M11 31 h1 v1 h-1Z M14 31 h5 v1 h-5Z M20 31 h1 v1 h-1Z M22 31 h1 v1 h-1Z M25 31 h4 v1 h-4Z M33 31 h1 v1 h-1Z M36 31 h2 v1 h-2Z M39 31 h3 v1 h-3Z M44 31 h2 v1 h-2Z M47 31 h1 v1 h-1Z M5 32 h1 v1 h-1Z M7 32 h3 v1 h-3Z M12 32 h2 v1 h-2Z M16 32 h1 v1 h-1Z M22 32 h1 v1 h-1Z M28 32 h1 v1 h-1Z M31 32 h3 v1 h-3Z M35 32 h1 v1 h-1Z M39 32 h2 v1 h-2Z M42 32 h1 v1 h-1Z M45 32 h2 v1 h-2Z M48 32 h1 v1 h-1Z M7 33 h2 v1 h-2Z M13 33 h1 v1 h-1Z M17 33 h2 v1 h-2Z M20 33 h1 v1 h-1Z M22 33 h1 v1 h-1Z M24 33 h1 v1 h-1Z M26 33 h2 v1 h-2Z M34 33 h3 v1 h-3Z M48 33 h1 v1 h-1Z M4 34 h6 v1 h-6Z M11 34 h4 v1 h-4Z M16 34 h4 v1 h-4Z M21 34 h1 v1 h-1Z M23 34 h1 v1 h-1Z M25 34 h3 v1 h-3Z M31 34 h3 v1 h-3Z M35 34 h2 v1 h-2Z M40 34 h1 v1 h-1Z M44 34 h5 v1 h-5Z M5 35 h2 v1 h-2Z M8 35 h1 v1 h-1Z M11 35 h2 v1 h-2Z M16 35 h1 v1 h-1Z M19 35 h1 v1 h-1Z M21 35 h1 v1 h-1Z M23 35 h5 v1 h-5Z M31 35 h2 v1 h-2Z M34 35 h3 v1 h-3Z M40 35 h2 v1 h-2Z M44 35 h2 v1 h-2Z M4 36 h4 v1 h-4Z M9 36 h1 v1 h-1Z M15 36 h4 v1 h-4Z M20 36 h2 v1 h-2Z M24 36 h1 v1 h-1Z M30 36 h2 v1 h-2Z M35 36 h5 v1 h-5Z M42 36 h1 v1 h-1Z M45 36 h4 v1 h-4Z M5 37 h1 v1 h-1Z M9 37 h1 v1 h-1Z M12 37 h2 v1 h-2Z M15 37 h1 v1 h-1Z M17 37 h2 v1 h-2Z M20 37 h1 v1 h-1Z M23 37 h2 v1 h-2Z M26 37 h2 v1 h-2Z M29 37 h2 v1 h-2Z M32 37 h2 v1 h-2Z M35 37 h1 v1 h-1Z M37 37 h3 v1 h-3Z M42 37 h1 v1 h-1Z M44 37 h1 v1 h-1Z M47 37 h2 v1 h-2Z M12 38 h1 v1 h-1Z M17 38 h1 v1 h-1Z M20 38 h1 v1 h-1Z M22 38 h1 v1 h-1Z M24 38 h1 v1 h-1Z M26 38 h4 v1 h-4Z M32 38 h1 v1 h-1Z M36 38 h2 v1 h-2Z M40 38 h2 v1 h-2Z M44 38 h1 v1 h-1Z M46 38 h1 v1 h-1Z M11 39 h1 v1 h-1Z M13 39 h2 v1 h-2Z M17 39 h1 v1 h-1Z M19 39 h4 v1 h-4Z M24 39 h1 v1 h-1Z M28 39 h1 v1 h-1Z M30 39 h3 v1 h-3Z M38 39 h1 v1 h-1Z M40 39 h4 v1 h-4Z M46 39 h2 v1 h-2Z M13 40 h1 v1 h-1Z M15 40 h3 v1 h-3Z M19 40 h3 v1 h-3Z M29 40 h3 v1 h-3Z M36 40 h2 v1 h-2Z M39 40 h1 v1 h-1Z M46 40 h1 v1 h-1Z M15 41 h7 v1 h-7Z M23 41 h1 v1 h-1Z M29 41 h1 v1 h-1Z M32 41 h1 v1 h-1Z M36 41 h1 v1 h-1Z M38 41 h2 v1 h-2Z M45 41 h4 v1 h-4Z M13 42 h1 v1 h-1Z M16 42 h1 v1 h-1Z M20 42 h4 v1 h-4Z M32 42 h3 v1 h-3Z M36 42 h4 v1 h-4Z M46 42 h3 v1 h-3Z M16 43 h2 v1 h-2Z M19 43 h1 v1 h-1Z M23 43 h1 v1 h-1Z M29 43 h2 v1 h-2Z M32 43 h3 v1 h-3Z M37 43 h1 v1 h-1Z M47 43 h2 v1 h-2Z M14 44 h1 v1 h-1Z M17 44 h4 v1 h-4Z M23 44 h1 v1 h-1Z M29 44 h1 v1 h-1Z M31 44 h1 v1 h-1Z M34 44 h1 v1 h-1Z M37 44 h1 v1 h-1Z M45 44 h1 v1 h-1Z M48 44 h1 v1 h-1Z M14 45 h2 v1 h-2Z M17 45 h1 v1 h-1Z M19 45 h1 v1 h-1Z M23 45 h6 v1 h-6Z M30 45 h3 v1 h-3Z M38 45 h2 v1 h-2Z M42 45 h2 v1 h-2Z M45 45 h2 v1 h-2Z M13 46 h1 v1 h-1Z M19 46 h4 v1 h-4Z M25 46 h3 v1 h-3Z M29 46 h1 v1 h-1Z M31 46 h2 v1 h-2Z M36 46 h1 v1 h-1Z M38 46 h1 v1 h-1Z M43 46 h1 v1 h-1Z M46 46 h3 v1 h-3Z M14 47 h1 v1 h-1Z M16 47 h2 v1 h-2Z M21 47 h1 v1 h-1Z M27 47 h7 v1 h-7Z M37 47 h2 v1 h-2Z M40 47 h2 v1 h-2Z M43 47 h1 v1 h-1Z M45 47 h3 v1 h-3Z M13 48 h1 v1 h-1Z M15 48 h1 v1 h-1Z M18 48 h1 v1 h-1Z M20 48 h1 v1 h-1Z M22 48 h3 v1 h-3Z M29 48 h2 v1 h-2Z M32 48 h1 v1 h-1Z M34 48 h1 v1 h-1Z M36 48 h1 v1 h-1Z M39 48 h3 v1 h-3Z M44 48 h1 v1 h-1Z M46 48 h3 v1 h-3Z " /><path class="qr-6 " stroke="transparent" fill="#fff" fill-opacity="1" d="M5 5 h5 v1 h-5Z M43 5 h5 v1 h-5Z M5 6 h1 v1 h-1Z M9 6 h1 v1 h-1Z M43 6 h1 v1 h-1Z M47 6 h1 v1 h-1Z M5 7 h1 v1 h-1Z M9 7 h1 v1 h-1Z M43 7 h1 v1 h-1Z M47 7 h1 v1 h-1Z M5 8 h1 v1 h-1Z M9 8 h1 v1 h-1Z M43 8 h1 v1 h-1Z M47 8 h1 v1 h-1Z M5 9 h5 v1 h-5Z M43 9 h5 v1 h-5Z M5 43 h5 v1 h-5Z M5 44 h1 v1 h-1Z M9 44 h1 v1 h-1Z M5 45 h1 v1 h-1Z M9 45 h1 v1 h-1Z M5 46 h1 v1 h-1Z M9 46 h1 v1 h-1Z M5 47 h5 v1 h-5Z " /><path class="qr-8 " stroke="transparent" fill="#fff" fill-opacity="1" d="M11 4 h1 v1 h-1Z M41 4 h1 v1 h-1Z M11 5 h1 v1 h-1Z M41 5 h1 v1 h-1Z M11 6 h1 v1 h-1Z M41 6 h1 v1 h-1Z M11 7 h1 v1 h-1Z M41 7 h1 v1 h-1Z M11 8 h1 v1 h-1Z M41 8 h1 v1 h-1Z M11 9 h1 v1 h-1Z M41 9 h1 v1 h-1Z M11 10 h1 v1 h-1Z M41 10 h1 v1 h-1Z M4 11 h8 v1 h-8Z M41 11 h8 v1 h-8Z M4 41 h8 v1 h-8Z M11 42 h1 v1 h-1Z M11 43 h1 v1 h-1Z M11 44 h1 v1 h-1Z M11 45 h1 v1 h-1Z M11 46 h1 v1 h-1Z M11 47 h1 v1 h-1Z M11 48 h1 v1 h-1Z " /><path class="qr-10 " stroke="transparent" fill="#fff" fill-opacity="1" d="M25 9 h3 v1 h-3Z M25 10 h1 v1 h-1Z M27 10 h1 v1 h-1Z M25 11 h3 v1 h-3Z M9 25 h3 v1 h-3Z M25 25 h3 v1 h-3Z M41 25 h3 v1 h-3Z M9 26 h1 v1 h-1Z M11 26 h1 v1 h-1Z M25 26 h1 v1 h-1Z M27 26 h1 v1 h-1Z M41 26 h1 v1 h-1Z M43 26 h1 v1 h-1Z M9 27 h3 v1 h-3Z M25 27 h3 v1 h-3Z M41 27 h3 v1 h-3Z M25 41 h3 v1 h-3Z M41 41 h3 v1 h-3Z M25 42 h1 v1 h-1Z M27 42 h1 v1 h-1Z M41 42 h1 v1 h-1Z M43 42 h1 v1 h-1Z M25 43 h3 v1 h-3Z M41 43 h3 v1 h-3Z " /><path class="qr-12 " stroke="transparent" fill="#fff" fill-opacity="1" d="M13 10 h1 v1 h-1Z M15 10 h1 v1 h-1Z M17 10 h1 v1 h-1Z M19 10 h1 v1 h-1Z M21 10 h1 v1 h-1Z M23 10 h1 v1 h-1Z M29 10 h1 v1 h-1Z M31 10 h1 v1 h-1Z M33 10 h1 v1 h-1Z M35 10 h1 v1 h-1Z M37 10 h1 v1 h-1Z M39 10 h1 v1 h-1Z M10 13 h1 v1 h-1Z M10 15 h1 v1 h-1Z M10 17 h1 v1 h-1Z M10 19 h1 v1 h-1Z M10 21 h1 v1 h-1Z M10 23 h1 v1 h-1Z M10 29 h1 v1 h-1Z M10 31 h1 v1 h-1Z M10 33 h1 v1 h-1Z M10 35 h1 v1 h-1Z M10 37 h1 v1 h-1Z M10 39 h1 v1 h-1Z " /><path class="qr-14 " stroke="transparent" fill="#fff" fill-opacity="1" d="M12 4 h1 v1 h-1Z M12 5 h1 v1 h-1Z M12 6 h1 v1 h-1Z M12 7 h1 v1 h-1Z M12 9 h1 v1 h-1Z M4 12 h2 v1 h-2Z M8 12 h2 v1 h-2Z M43 12 h1 v1 h-1Z M45 12 h4 v1 h-4Z M12 43 h1 v1 h-1Z M12 44 h1 v1 h-1Z M12 47 h1 v1 h-1Z M12 48 h1 v1 h-1Z " /><path class="qr-16 " stroke="transparent" fill="#fff" fill-opacity="1" d="M38 4 h2 v1 h-2Z M38 5 h1 v1 h-1Z M40 5 h1 v1 h-1Z M38 6 h1 v1 h-1Z M40 6 h1 v1 h-1Z M38 7 h1 v1 h-1Z M38 9 h3 v1 h-3Z M4 38 h4 v1 h-4Z M9 38 h1 v1 h-1Z M4 39 h1 v1 h-1Z M9 39 h1 v1 h-1Z M5 40 h2 v1 h-2Z M9 40 h1 v1 h-1Z " /><path class="qr-18 " stroke="transparent" fill="#fff" fill-opacity="1" d="M0 0 h53 v1 h-53Z M0 1 h53 v1 h-53Z M0 2 h53 v1 h-53Z M0 3 h53 v1 h-53Z M0 4 h4 v1 h-4Z M49 4 h4 v1 h-4Z M0 5 h4 v1 h-4Z M49 5 h4 v1 h-4Z M0 6 h4 v1 h-4Z M49 6 h4 v1 h-4Z M0 7 h4 v1 h-4Z M49 7 h4 v1 h-4Z M0 8 h4 v1 h-4Z M49 8 h4 v1 h-4Z M0 9 h4 v1 h-4Z M49 9 h4 v1 h-4Z M0 10 h4 v1 h-4Z M49 10 h4 v1 h-4Z M0 11 h4 v1 h-4Z M49 11 h4 v1 h-4Z M0 12 h4 v1 h-4Z M49 12 h4 v1 h-4Z M0 13 h4 v1 h-4Z M49 13 h4 v1 h-4Z M0 14 h4 v1 h-4Z M49 14 h4 v1 h-4Z M0 15 h4 v1 h-4Z M49 15 h4 v1 h-4Z M0 16 h4 v1 h-4Z M49 16 h4 v1 h-4Z M0 17 h4 v1 h-4Z M49 17 h4 v1 h-4Z M0 18 h4 v1 h-4Z M49 18 h4 v1 h-4Z M0 19 h4 v1 h-4Z M49 19 h4 v1 h-4Z M0 20 h4 v1 h-4Z M49 20 h4 v1 h-4Z M0 21 h4 v1 h-4Z M49 21 h4 v1 h-4Z M0 22 h4 v1 h-4Z M49 22 h4 v1 h-4Z M0 23 h4 v1 h-4Z M49 23 h4 v1 h-4Z M0 24 h4 v1 h-4Z M49 24 h4 v1 h-4Z M0 25 h4 v1 h-4Z M49 25 h4 v1 h-4Z M0 26 h4 v1 h-4Z M49 26 h4 v1 h-4Z M0 27 h4 v1 h-4Z M49 27 h4 v1 h-4Z M0 28 h4 v1 h-4Z M49 28 h4 v1 h-4Z M0 29 h4 v1 h-4Z M49 29 h4 v1 h-4Z M0 30 h4 v1 h-4Z M49 30 h4 v1 h-4Z M0 31 h4 v1 h-4Z M49 31 h4 v1 h-4Z M0 32 h4 v1 h-4Z M49 32 h4 v1 h-4Z M0 33 h4 v1 h-4Z M49 33 h4 v1 h-4Z M0 34 h4 v1 h-4Z M49 34 h4 v1 h-4Z M0 35 h4 v1 h-4Z M49 35 h4 v1 h-4Z M0 36 h4 v1 h-4Z M49 36 h4 v1 h-4Z M0 37 h4 v1 h-4Z M49 37 h4 v1 h-4Z M0 38 h4 v1 h-4Z M49 38 h4 v1 h-4Z M0 39 h4 v1 h-4Z M49 39 h4 v1 h-4Z M0 40 h4 v1 h-4Z M49 40 h4 v1 h-4Z M0 41 h4 v1 h-4Z M49 41 h4 v1 h-4Z M0 42 h4 v1 h-4Z M49 42 h4 v1 h-4Z M0 43 h4 v1 h-4Z M49 43 h4 v1 h-4Z M0 44 h4 v1 h-4Z M49 44 h4 v1 h-4Z M0 45 h4 v1 h-4Z M49 45 h4 v1 h-4Z M0 46 h4 v1 h-4Z M49 46 h4 v1 h-4Z M0 47 h4 v1 h-4Z M49 47 h4 v1 h-4Z M0 48 h4 v1 h-4Z M49 48 h4 v1 h-4Z M0 49 h53 v1 h-53Z M0 50 h53 v1 h-53Z M0 51 h53 v1 h-53Z M0 52 h53 v1 h-53Z " /><path class="qr-512 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 41 h1 v1 h-1Z " /><path class="qr-1024 " stroke="transparent" fill="#000" fill-opacity="1" d="M13 4 h1 v1 h-1Z M16 4 h2 v1 h-2Z M19 4 h3 v1 h-3Z M27 4 h1 v1 h-1Z M29 4 h1 v1 h-1Z M32 4 h3 v1 h-3Z M36 4 h2 v1 h-2Z M14 5 h1 v1 h-1Z M17 5 h1 v1 h-1Z M19 5 h1 v1 h-1Z M21 5 h2 v1 h-2Z M24 5 h2 v1 h-2Z M29 5 h1 v1 h-1Z M32 5 h4 v1 h-4Z M37 5 h1 v1 h-1Z M13 6 h4 v1 h-4Z M18 6 h8 v1 h-8Z M27 6 h1 v1 h-1Z M30 6 h1 v1 h-1Z M33 6 h2 v1 h-2Z M16 7 h1 v1 h-1Z M20 7 h1 v1 h-1Z M29 7 h1 v1 h-1Z M31 7 h4 v1 h-4Z M37 7 h1 v1 h-1Z M14 8 h1 v1 h-1Z M17 8 h1 v1 h-1Z M21 8 h1 v1 h-1Z M31 8 h1 v1 h-1Z M33 8 h1 v1 h-1Z M35 8 h2 v1 h-2Z M14 9 h2 v1 h-2Z M18 9 h2 v1 h-2Z M21 9 h2 v1 h-2Z M30 9 h3 v1 h-3Z M34 9 h2 v1 h-2Z M37 9 h1 v1 h-1Z M14 11 h6 v1 h-6Z M30 11 h3 v1 h-3Z M36 11 h4 v1 h-4Z M14 12 h1 v1 h-1Z M19 12 h1 v1 h-1Z M21 12 h1 v1 h-1Z M30 12 h1 v1 h-1Z M36 12 h2 v1 h-2Z M7 13 h2 v1 h-2Z M13 13 h1 v1 h-1Z M16 13 h2 v1 h-2Z M20 13 h1 v1 h-1Z M22 13 h1 v1 h-1Z M24 13 h1 v1 h-1Z M26 13 h1 v1 h-1Z M30 13 h1 v1 h-1Z M33 13 h2 v1 h-2Z M36 13 h2 v1 h-2Z M39 13 h1 v1 h-1Z M41 13 h4 v1 h-4Z M46 13 h1 v1 h-1Z M4 14 h1 v1 h-1Z M9 14 h1 v1 h-1Z M12 14 h1 v1 h-1Z M17 14 h2 v1 h-2Z M20 14 h1 v1 h-1Z M23 14 h1 v1 h-1Z M25 14 h1 v1 h-1Z M27 14 h2 v1 h-2Z M30 14 h1 v1 h-1Z M32 14 h4 v1 h-4Z M38 14 h3 v1 h-3Z M42 14 h3 v1 h-3Z M47 14 h1 v1 h-1Z M4 15 h3 v1 h-3Z M8 15 h1 v1 h-1Z M11 15 h1 v1 h-1Z M14 15 h2 v1 h-2Z M20 15 h1 v1 h-1Z M22 15 h1 v1 h-1Z M26 15 h1 v1 h-1Z M29 15 h2 v1 h-2Z M36 15 h1 v1 h-1Z M39 15 h3 v1 h-3Z M43 15 h2 v1 h-2Z M47 15 h2 v1 h-2Z M4 16 h3 v1 h-3Z M8 16 h2 v1 h-2Z M14 16 h3 v1 h-3Z M18 16 h1 v1 h-1Z M20 16 h2 v1 h-2Z M25 16 h1 v1 h-1Z M28 16 h3 v1 h-3Z M33 16 h3 v1 h-3Z M43 16 h1 v1 h-1Z M45 16 h4 v1 h-4Z M7 17 h1 v1 h-1Z M9 17 h1 v1 h-1Z M12 17 h1 v1 h-1Z M14 17 h1 v1 h-1Z M17 17 h1 v1 h-1Z M22 17 h2 v1 h-2Z M28 17 h3 v1 h-3Z M33 17 h1 v1 h-1Z M35 17 h2 v1 h-2Z M41 17 h3 v1 h-3Z M45 17 h3 v1 h-3Z M6 18 h2 v1 h-2Z M12 18 h4 v1 h-4Z M18 18 h1 v1 h-1Z M22 18 h1 v1 h-1Z M26 18 h1 v1 h-1Z M30 18 h1 v1 h-1Z M32 18 h2 v1 h-2Z M35 18 h1 v1 h-1Z M39 18 h2 v1 h-2Z M42 18 h1 v1 h-1Z M44 18 h1 v1 h-1Z M4 19 h4 v1 h-4Z M12 19 h1 v1 h-1Z M14 19 h1 v1 h-1Z M16 19 h1 v1 h-1Z M18 19 h1 v1 h-1Z M20 19 h1 v1 h-1Z M22 19 h2 v1 h-2Z M25 19 h7 v1 h-7Z M33 19 h1 v1 h-1Z M36 19 h1 v1 h-1Z M39 19 h1 v1 h-1Z M44 19 h3 v1 h-3Z M4 20 h1 v1 h-1Z M7 20 h2 v1 h-2Z M11 20 h1 v1 h-1Z M14 20 h2 v1 h-2Z M18 20 h2 v1 h-2Z M21 20 h3 v1 h-3Z M26 20 h1 v1 h-1Z M31 20 h6 v1 h-6Z M40 20 h4 v1 h-4Z M46 20 h1 v1 h-1Z M5 21 h1 v1 h-1Z M8 21 h1 v1 h-1Z M11 21 h2 v1 h-2Z M14 21 h4 v1 h-4Z M19 21 h1 v1 h-1Z M21 21 h2 v1 h-2Z M24 21 h1 v1 h-1Z M26 21 h1 v1 h-1Z M30 21 h1 v1 h-1Z M32 21 h3 v1 h-3Z M36 21 h4 v1 h-4Z M43 21 h1 v1 h-1Z M47 21 h2 v1 h-2Z M5 22 h2 v1 h-2Z M8 22 h1 v1 h-1Z M19 22 h1 v1 h-1Z M21 22 h1 v1 h-1Z M23 22 h1 v1 h-1Z M26 22 h6 v1 h-6Z M34 22 h10 v1 h-10Z M47 22 h1 v1 h-1Z M4 23 h4 v1 h-4Z M12 23 h2 v1 h-2Z M16 23 h2 v1 h-2Z M22 23 h1 v1 h-1Z M25 23 h1 v1 h-1Z M27 23 h1 v1 h-1Z M33 23 h1 v1 h-1Z M39 23 h1 v1 h-1Z M41 23 h2 v1 h-2Z M44 23 h1 v1 h-1Z M47 23 h2 v1 h-2Z M4 24 h1 v1 h-1Z M7 24 h1 v1 h-1Z M13 24 h3 v1 h-3Z M19 24 h1 v1 h-1Z M21 24 h1 v1 h-1Z M30 24 h1 v1 h-1Z M32 24 h2 v1 h-2Z M35 24 h1 v1 h-1Z M37 24 h2 v1 h-2Z M46 24 h3 v1 h-3Z M6 25 h1 v1 h-1Z M20 25 h1 v1 h-1Z M31 25 h2 v1 h-2Z M34 25 h1 v1 h-1Z M36 25 h2 v1 h-2Z M39 25 h1 v1 h-1Z M45 25 h2 v1 h-2Z M48 25 h1 v1 h-1Z M5 26 h3 v1 h-3Z M17 26 h1 v1 h-1Z M19 26 h1 v1 h-1Z M21 26 h2 v1 h-2Z M29 26 h1 v1 h-1Z M32 26 h1 v1 h-1Z M36 26 h2 v1 h-2Z M39 26 h1 v1 h-1Z M47 26 h2 v1 h-2Z M4 27 h2 v1 h-2Z M7 27 h1 v1 h-1Z M14 27 h1 v1 h-1Z M16 27 h2 v1 h-2Z M19 27 h2 v1 h-2Z M23 27 h1 v1 h-1Z M29 27 h1 v1 h-1Z M31 27 h2 v1 h-2Z M35 27 h1 v1 h-1Z M37 27 h1 v1 h-1Z M45 27 h1 v1 h-1Z M47 27 h2 v1 h-2Z M5 28 h2 v1 h-2Z M13 28 h2 v1 h-2Z M17 28 h3 v1 h-3Z M21 28 h2 v1 h-2Z M29 28 h1 v1 h-1Z M31 28 h1 v1 h-1Z M35 28 h4 v1 h-4Z M47 28 h1 v1 h-1Z M4 29 h1 v1 h-1Z M9 29 h1 v1 h-1Z M16 29 h3 v1 h-3Z M21 29 h2 v1 h-2Z M24 29 h1 v1 h-1Z M26 29 h2 v1 h-2Z M31 29 h1 v1 h-1Z M34 29 h1 v1 h-1Z M37 29 h2 v1 h-2Z M42 29 h2 v1 h-2Z M45 29 h1 v1 h-1Z M48 29 h1 v1 h-1Z M4 30 h5 v1 h-5Z M12 30 h1 v1 h-1Z M14 30 h1 v1 h-1Z M18 30 h5 v1 h-5Z M25 30 h1 v1 h-1Z M29 30 h1 v1 h-1Z M31 30 h1 v1 h-1Z M33 30 h2 v1 h-2Z M36 30 h1 v1 h-1Z M38 30 h2 v1 h-2Z M45 30 h1 v1 h-1Z M48 30 h1 v1 h-1Z M4 31 h1 v1 h-1Z M7 31 h3 v1 h-3Z M12 31 h2 v1 h-2Z M19 31 h1 v1 h-1Z M21 31 h1 v1 h-1Z M23 31 h2 v1 h-2Z M29 31 h4 v1 h-4Z M34 31 h2 v1 h-2Z M38 31 h1 v1 h-1Z M42 31 h2 v1 h-2Z M46 31 h1 v1 h-1Z M48 31 h1 v1 h-1Z M4 32 h1 v1 h-1Z M6 32 h1 v1 h-1Z M11 32 h1 v1 h-1Z M14 32 h2 v1 h-2Z M17 32 h5 v1 h-5Z M23 32 h5 v1 h-5Z M29 32 h2 v1 h-2Z M34 32 h1 v1 h-1Z M36 32 h3 v1 h-3Z M41 32 h1 v1 h-1Z M43 32 h2 v1 h-2Z M47 32 h1 v1 h-1Z M4 33 h3 v1 h-3Z M9 33 h1 v1 h-1Z M11 33 h2 v1 h-2Z M14 33 h3 v1 h-3Z M19 33 h1 v1 h-1Z M21 33 h1 v1 h-1Z M23 33 h1 v1 h-1Z M25 33 h1 v1 h-1Z M28 33 h6 v1 h-6Z M37 33 h11 v1 h-11Z M15 34 h1 v1 h-1Z M20 34 h1 v1 h-1Z M22 34 h1 v1 h-1Z M24 34 h1 v1 h-1Z M28 34 h3 v1 h-3Z M34 34 h1 v1 h-1Z M37 34 h3 v1 h-3Z M41 34 h3 v1 h-3Z M4 35 h1 v1 h-1Z M7 35 h1 v1 h-1Z M9 35 h1 v1 h-1Z M13 35 h3 v1 h-3Z M17 35 h2 v1 h-2Z M20 35 h1 v1 h-1Z M22 35 h1 v1 h-1Z M28 35 h3 v1 h-3Z M33 35 h1 v1 h-1Z M37 35 h3 v1 h-3Z M42 35 h2 v1 h-2Z M46 35 h3 v1 h-3Z M8 36 h1 v1 h-1Z M11 36 h4 v1 h-4Z M19 36 h1 v1 h-1Z M22 36 h2 v1 h-2Z M25 36 h5 v1 h-5Z M32 36 h3 v1 h-3Z M40 36 h2 v1 h-2Z M43 36 h2 v1 h-2Z M4 37 h1 v1 h-1Z M6 37 h3 v1 h-3Z M11 37 h1 v1 h-1Z M14 37 h1 v1 h-1Z M16 37 h1 v1 h-1Z M19 37 h1 v1 h-1Z M21 37 h2 v1 h-2Z M25 37 h1 v1 h-1Z M28 37 h1 v1 h-1Z M31 37 h1 v1 h-1Z M34 37 h1 v1 h-1Z M36 37 h1 v1 h-1Z M40 37 h2 v1 h-2Z M43 37 h1 v1 h-1Z M45 37 h2 v1 h-2Z M11 38 h1 v1 h-1Z M13 38 h4 v1 h-4Z M18 38 h2 v1 h-2Z M21 38 h1 v1 h-1Z M23 38 h1 v1 h-1Z M25 38 h1 v1 h-1Z M30 38 h2 v1 h-2Z M33 38 h3 v1 h-3Z M38 38 h2 v1 h-2Z M42 38 h2 v1 h-2Z M45 38 h1 v1 h-1Z M47 38 h2 v1 h-2Z M12 39 h1 v1 h-1Z M15 39 h2 v1 h-2Z M18 39 h1 v1 h-1Z M23 39 h1 v1 h-1Z M25 39 h3 v1 h-3Z M29 39 h1 v1 h-1Z M33 39 h5 v1 h-5Z M39 39 h1 v1 h-1Z M44 39 h2 v1 h-2Z M48 39 h1 v1 h-1Z M11 40 h2 v1 h-2Z M14 40 h1 v1 h-1Z M18 40 h1 v1 h-1Z M22 40 h2 v1 h-2Z M32 40 h4 v1 h-4Z M38 40 h1 v1 h-1Z M45 40 h1 v1 h-1Z M47 40 h2 v1 h-2Z M13 41 h2 v1 h-2Z M22 41 h1 v1 h-1Z M30 41 h2 v1 h-2Z M33 41 h3 v1 h-3Z M37 41 h1 v1 h-1Z M14 42 h2 v1 h-2Z M17 42 h3 v1 h-3Z M29 42 h3 v1 h-3Z M35 42 h1 v1 h-1Z M45 42 h1 v1 h-1Z M13 43 h3 v1 h-3Z M18 43 h1 v1 h-1Z M20 43 h3 v1 h-3Z M31 43 h1 v1 h-1Z M35 43 h2 v1 h-2Z M38 43 h2 v1 h-2Z M45 43 h2 v1 h-2Z M13 44 h1 v1 h-1Z M15 44 h2 v1 h-2Z M21 44 h2 v1 h-2Z M30 44 h1 v1 h-1Z M32 44 h2 v1 h-2Z M35 44 h2 v1 h-2Z M38 44 h2 v1 h-2Z M46 44 h2 v1 h-2Z M13 45 h1 v1 h-1Z M16 45 h1 v1 h-1Z M18 45 h1 v1 h-1Z M20 45 h3 v1 h-3Z M29 45 h1 v1 h-1Z M33 45 h5 v1 h-5Z M40 45 h2 v1 h-2Z M44 45 h1 v1 h-1Z M47 45 h2 v1 h-2Z M14 46 h5 v1 h-5Z M23 46 h2 v1 h-2Z M28 46 h1 v1 h-1Z M30 46 h1 v1 h-1Z M33 46 h3 v1 h-3Z M37 46 h1 v1 h-1Z M39 46 h4 v1 h-4Z M44 46 h2 v1 h-2Z M13 47 h1 v1 h-1Z M15 47 h1 v1 h-1Z M18 47 h3 v1 h-3Z M22 47 h5 v1 h-5Z M34 47 h3 v1 h-3Z M39 47 h1 v1 h-1Z M42 47 h1 v1 h-1Z M44 47 h1 v1 h-1Z M48 47 h1 v1 h-1Z M14 48 h1 v1 h-1Z M16 48 h2 v1 h-2Z M19 48 h1 v1 h-1Z M21 48 h1 v1 h-1Z M25 48 h4 v1 h-4Z M31 48 h1 v1 h-1Z M33 48 h1 v1 h-1Z M35 48 h1 v1 h-1Z M37 48 h2 v1 h-2Z M42 48 h2 v1 h-2Z M45 48 h1 v1 h-1Z " /><path class="qr-1536 " stroke="transparent" fill="#000" fill-opacity="1" d="M4 4 h7 v1 h-7Z M42 4 h7 v1 h-7Z M4 5 h1 v1 h-1Z M10 5 h1 v1 h-1Z M42 5 h1 v1 h-1Z M48 5 h1 v1 h-1Z M4 6 h1 v1 h-1Z M10 6 h1 v1 h-1Z M42 6 h1 v1 h-1Z M48 6 h1 v1 h-1Z M4 7 h1 v1 h-1Z M10 7 h1 v1 h-1Z M42 7 h1 v1 h-1Z M48 7 h1 v1 h-1Z M4 8 h1 v1 h-1Z M10 8 h1 v1 h-1Z M42 8 h1 v1 h-1Z M48 8 h1 v1 h-1Z M4 9 h1 v1 h-1Z M10 9 h1 v1 h-1Z M42 9 h1 v1 h-1Z M48 9 h1 v1 h-1Z M4 10 h7 v1 h-7Z M42 10 h7 v1 h-7Z M4 42 h7 v1 h-7Z M4 43 h1 v1 h-1Z M10 43 h1 v1 h-1Z M4 44 h1 v1 h-1Z M10 44 h1 v1 h-1Z M4 45 h1 v1 h-1Z M10 45 h1 v1 h-1Z M4 46 h1 v1 h-1Z M10 46 h1 v1 h-1Z M4 47 h1 v1 h-1Z M10 47 h1 v1 h-1Z M4 48 h7 v1 h-7Z " /><path class="qr-2560 " stroke="transparent" fill="#000" fill-opacity="1" d="M24 8 h5 v1 h-5Z M24 9 h1 v1 h-1Z M28 9 h1 v1 h-1Z M24 10 h1 v1 h-1Z M26 10 h1 v1 h-1Z M28 10 h1 v1 h-1Z M24 11 h1 v1 h-1Z M28 11 h1 v1 h-1Z M24 12 h5 v1 h-5Z M8 24 h5 v1 h-5Z M24 24 h5 v1 h-5Z M40 24 h5 v1 h-5Z M8 25 h1 v1 h-1Z M12 25 h1 v1 h-1Z M24 25 h1 v1 h-1Z M28 25 h1 v1 h-1Z M40 25 h1 v1 h-1Z M44 25 h1 v1 h-1Z M8 26 h1 v1 h-1Z M10 26 h1 v1 h-1Z M12 26 h1 v1 h-1Z M24 26 h1 v1 h-1Z M26 26 h1 v1 h-1Z M28 26 h1 v1 h-1Z M40 26 h1 v1 h-1Z M42 26 h1 v1 h-1Z M44 26 h1 v1 h-1Z M8 27 h1 v1 h-1Z M12 27 h1 v1 h-1Z M24 27 h1 v1 h-1Z M28 27 h1 v1 h-1Z M40 27 h1 v1 h-1Z M44 27 h1 v1 h-1Z M8 28 h5 v1 h-5Z M24 28 h5 v1 h-5Z M40 28 h5 v1 h-5Z M24 40 h5 v1 h-5Z M40 40 h5 v1 h-5Z M24 41 h1 v1 h-1Z M28 41 h1 v1 h-1Z M40 41 h1 v1 h-1Z M44 41 h1 v1 h-1Z M24 42 h1 v1 h-1Z M26 42 h1 v1 h-1Z M28 42 h1 v1 h-1Z M40 42 h1 v1 h-1Z M42 42 h1 v1 h-1Z M44 42 h1 v1 h-1Z M24 43 h1 v1 h-1Z M28 43 h1 v1 h-1Z M40 43 h1 v1 h-1Z M44 43 h1 v1 h-1Z M24 44 h5 v1 h-5Z M40 44 h5 v1 h-5Z " /><path class="qr-3072 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 10 h1 v1 h-1Z M14 10 h1 v1 h-1Z M16 10 h1 v1 h-1Z M18 10 h1 v1 h-1Z M20 10 h1 v1 h-1Z M22 10 h1 v1 h-1Z M30 10 h1 v1 h-1Z M32 10 h1 v1 h-1Z M34 10 h1 v1 h-1Z M36 10 h1 v1 h-1Z M38 10 h1 v1 h-1Z M40 10 h1 v1 h-1Z M10 12 h1 v1 h-1Z M10 14 h1 v1 h-1Z M10 16 h1 v1 h-1Z M10 18 h1 v1 h-1Z M10 20 h1 v1 h-1Z M10 22 h1 v1 h-1Z M10 30 h1 v1 h-1Z M10 32 h1 v1 h-1Z M10 34 h1 v1 h-1Z M10 36 h1 v1 h-1Z M10 38 h1 v1 h-1Z M10 40 h1 v1 h-1Z " /><path class="qr-3584 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 8 h1 v1 h-1Z M12 11 h1 v1 h-1Z M6 12 h2 v1 h-2Z M11 12 h2 v1 h-2Z M41 12 h2 v1 h-2Z M44 12 h1 v1 h-1Z M12 42 h1 v1 h-1Z M12 45 h1 v1 h-1Z M12 46 h1 v1 h-1Z " /><path class="qr-4096 " stroke="transparent" fill="#000" fill-opacity="1" d="M40 4 h1 v1 h-1Z M39 5 h1 v1 h-1Z M39 6 h1 v1 h-1Z M39 7 h2 v1 h-2Z M38 8 h3 v1 h-3Z M8 38 h1 v1 h-1Z M5 39 h4 v1 h-4Z M4 40 h1 v1 h-1Z M7 40 h2 v1 h-2Z " /><path class="qr-5632 " stroke="transparent" fill="#000" fill-opacity="1" d="M6 6 h3 v1 h-3Z M44 6 h3 v1 h-3Z M6 7 h3 v1 h-3Z M44 7 h3 v1 h-3Z M6 8 h3 v1 h-3Z M44 8 h3 v1 h-3Z M6 44 h3 v1 h-3Z M6 45 h3 v1 h-3Z M6 46 h3 v1 h-3Z " /></svg>

    </a>
    <figcaption aria-hidden="true" class="hidden" hidden>Un don Liberapay pour Stéphane HUC</figcaption>
</figure>


<h3 id="paypal">Paypal</h3>
<ul>
<li><a href="https://paypal.me/hucste" rel="external">https://paypal.me/hucste</a></li>
</ul>


<figure class="pure-img">
    <a href="/svg/qrcode/paypal.svg" title="Un don Paypal pour Stéphane HUC">
    <svg xmlns="http://www.w3.org/2000/svg" class="qr-svg " height="128" viewBox="0 0 53 53" width="128">
<defs><style>rect{shape-rendering:crispEdges}</style></defs>
<path class="qr-4 " stroke="transparent" fill="#fff" fill-opacity="1" d="M15 4 h1 v1 h-1Z M18 4 h3 v1 h-3Z M24 4 h1 v1 h-1Z M27 4 h7 v1 h-7Z M35 4 h1 v1 h-1Z M16 5 h6 v1 h-6Z M25 5 h2 v1 h-2Z M29 5 h4 v1 h-4Z M34 5 h1 v1 h-1Z M36 5 h1 v1 h-1Z M13 6 h5 v1 h-5Z M19 6 h7 v1 h-7Z M30 6 h2 v1 h-2Z M35 6 h2 v1 h-2Z M13 7 h1 v1 h-1Z M15 7 h1 v1 h-1Z M17 7 h1 v1 h-1Z M20 7 h3 v1 h-3Z M25 7 h4 v1 h-4Z M32 7 h1 v1 h-1Z M35 7 h1 v1 h-1Z M37 7 h1 v1 h-1Z M13 8 h1 v1 h-1Z M15 8 h1 v1 h-1Z M18 8 h2 v1 h-2Z M22 8 h1 v1 h-1Z M29 8 h1 v1 h-1Z M31 8 h2 v1 h-2Z M13 9 h1 v1 h-1Z M15 9 h1 v1 h-1Z M21 9 h2 v1 h-2Z M29 9 h1 v1 h-1Z M31 9 h1 v1 h-1Z M35 9 h2 v1 h-2Z M13 11 h4 v1 h-4Z M19 11 h4 v1 h-4Z M29 11 h2 v1 h-2Z M34 11 h1 v1 h-1Z M39 11 h1 v1 h-1Z M17 12 h1 v1 h-1Z M19 12 h1 v1 h-1Z M29 12 h1 v1 h-1Z M32 12 h4 v1 h-4Z M37 12 h3 v1 h-3Z M5 13 h1 v1 h-1Z M8 13 h1 v1 h-1Z M11 13 h2 v1 h-2Z M15 13 h1 v1 h-1Z M17 13 h2 v1 h-2Z M21 13 h3 v1 h-3Z M34 13 h4 v1 h-4Z M40 13 h1 v1 h-1Z M42 13 h4 v1 h-4Z M47 13 h1 v1 h-1Z M4 14 h3 v1 h-3Z M8 14 h1 v1 h-1Z M12 14 h3 v1 h-3Z M16 14 h1 v1 h-1Z M18 14 h2 v1 h-2Z M21 14 h1 v1 h-1Z M24 14 h1 v1 h-1Z M30 14 h1 v1 h-1Z M36 14 h1 v1 h-1Z M40 14 h2 v1 h-2Z M43 14 h1 v1 h-1Z M45 14 h1 v1 h-1Z M48 14 h1 v1 h-1Z M4 15 h2 v1 h-2Z M8 15 h2 v1 h-2Z M12 15 h1 v1 h-1Z M22 15 h1 v1 h-1Z M24 15 h2 v1 h-2Z M27 15 h3 v1 h-3Z M31 15 h2 v1 h-2Z M36 15 h1 v1 h-1Z M39 15 h4 v1 h-4Z M47 15 h1 v1 h-1Z M5 16 h1 v1 h-1Z M9 16 h1 v1 h-1Z M11 16 h2 v1 h-2Z M14 16 h3 v1 h-3Z M18 16 h5 v1 h-5Z M25 16 h1 v1 h-1Z M27 16 h1 v1 h-1Z M29 16 h2 v1 h-2Z M32 16 h2 v1 h-2Z M37 16 h1 v1 h-1Z M39 16 h1 v1 h-1Z M45 16 h1 v1 h-1Z M47 16 h2 v1 h-2Z M8 17 h1 v1 h-1Z M11 17 h1 v1 h-1Z M13 17 h1 v1 h-1Z M17 17 h1 v1 h-1Z M19 17 h1 v1 h-1Z M22 17 h3 v1 h-3Z M28 17 h2 v1 h-2Z M31 17 h3 v1 h-3Z M35 17 h1 v1 h-1Z M38 17 h2 v1 h-2Z M41 17 h1 v1 h-1Z M44 17 h4 v1 h-4Z M5 18 h1 v1 h-1Z M9 18 h1 v1 h-1Z M12 18 h2 v1 h-2Z M15 18 h3 v1 h-3Z M20 18 h3 v1 h-3Z M24 18 h2 v1 h-2Z M28 18 h2 v1 h-2Z M31 18 h2 v1 h-2Z M36 18 h1 v1 h-1Z M38 18 h1 v1 h-1Z M41 18 h1 v1 h-1Z M45 18 h1 v1 h-1Z M48 18 h1 v1 h-1Z M6 19 h2 v1 h-2Z M9 19 h1 v1 h-1Z M11 19 h1 v1 h-1Z M14 19 h1 v1 h-1Z M16 19 h2 v1 h-2Z M20 19 h2 v1 h-2Z M23 19 h1 v1 h-1Z M25 19 h2 v1 h-2Z M28 19 h1 v1 h-1Z M31 19 h2 v1 h-2Z M34 19 h3 v1 h-3Z M38 19 h2 v1 h-2Z M43 19 h1 v1 h-1Z M4 20 h1 v1 h-1Z M6 20 h2 v1 h-2Z M9 20 h1 v1 h-1Z M11 20 h1 v1 h-1Z M16 20 h1 v1 h-1Z M18 20 h6 v1 h-6Z M25 20 h3 v1 h-3Z M29 20 h4 v1 h-4Z M34 20 h1 v1 h-1Z M39 20 h2 v1 h-2Z M43 20 h1 v1 h-1Z M45 20 h3 v1 h-3Z M4 21 h2 v1 h-2Z M11 21 h1 v1 h-1Z M13 21 h1 v1 h-1Z M20 21 h1 v1 h-1Z M23 21 h1 v1 h-1Z M25 21 h2 v1 h-2Z M28 21 h1 v1 h-1Z M30 21 h2 v1 h-2Z M33 21 h4 v1 h-4Z M38 21 h2 v1 h-2Z M41 21 h7 v1 h-7Z M4 22 h1 v1 h-1Z M6 22 h3 v1 h-3Z M11 22 h1 v1 h-1Z M15 22 h2 v1 h-2Z M18 22 h1 v1 h-1Z M21 22 h1 v1 h-1Z M23 22 h3 v1 h-3Z M30 22 h1 v1 h-1Z M32 22 h1 v1 h-1Z M35 22 h1 v1 h-1Z M42 22 h3 v1 h-3Z M47 22 h1 v1 h-1Z M5 23 h1 v1 h-1Z M7 23 h3 v1 h-3Z M13 23 h2 v1 h-2Z M16 23 h5 v1 h-5Z M23 23 h1 v1 h-1Z M26 23 h1 v1 h-1Z M29 23 h3 v1 h-3Z M33 23 h1 v1 h-1Z M35 23 h6 v1 h-6Z M43 23 h1 v1 h-1Z M45 23 h1 v1 h-1Z M47 23 h1 v1 h-1Z M4 24 h2 v1 h-2Z M7 24 h1 v1 h-1Z M13 24 h1 v1 h-1Z M15 24 h1 v1 h-1Z M17 24 h2 v1 h-2Z M23 24 h1 v1 h-1Z M29 24 h1 v1 h-1Z M32 24 h1 v1 h-1Z M35 24 h3 v1 h-3Z M39 24 h1 v1 h-1Z M45 24 h2 v1 h-2Z M48 24 h1 v1 h-1Z M6 25 h1 v1 h-1Z M13 25 h2 v1 h-2Z M16 25 h2 v1 h-2Z M19 25 h1 v1 h-1Z M21 25 h1 v1 h-1Z M29 25 h1 v1 h-1Z M31 25 h3 v1 h-3Z M37 25 h1 v1 h-1Z M46 25 h3 v1 h-3Z M6 26 h2 v1 h-2Z M13 26 h3 v1 h-3Z M18 26 h1 v1 h-1Z M20 26 h2 v1 h-2Z M31 26 h1 v1 h-1Z M33 26 h1 v1 h-1Z M35 26 h1 v1 h-1Z M37 26 h2 v1 h-2Z M46 26 h1 v1 h-1Z M5 27 h3 v1 h-3Z M16 27 h3 v1 h-3Z M22 27 h1 v1 h-1Z M30 27 h2 v1 h-2Z M33 27 h4 v1 h-4Z M38 27 h1 v1 h-1Z M45 27 h4 v1 h-4Z M6 28 h2 v1 h-2Z M14 28 h1 v1 h-1Z M16 28 h3 v1 h-3Z M20 28 h1 v1 h-1Z M23 28 h1 v1 h-1Z M31 28 h1 v1 h-1Z M34 28 h3 v1 h-3Z M38 28 h1 v1 h-1Z M48 28 h1 v1 h-1Z M5 29 h3 v1 h-3Z M9 29 h1 v1 h-1Z M12 29 h1 v1 h-1Z M14 29 h1 v1 h-1Z M16 29 h2 v1 h-2Z M20 29 h1 v1 h-1Z M22 29 h2 v1 h-2Z M25 29 h2 v1 h-2Z M28 29 h1 v1 h-1Z M31 29 h2 v1 h-2Z M34 29 h1 v1 h-1Z M36 29 h1 v1 h-1Z M41 29 h1 v1 h-1Z M44 29 h2 v1 h-2Z M5 30 h1 v1 h-1Z M7 30 h3 v1 h-3Z M11 30 h1 v1 h-1Z M13 30 h1 v1 h-1Z M15 30 h1 v1 h-1Z M18 30 h2 v1 h-2Z M25 30 h6 v1 h-6Z M32 30 h1 v1 h-1Z M35 30 h1 v1 h-1Z M42 30 h2 v1 h-2Z M47 30 h1 v1 h-1Z M5 31 h1 v1 h-1Z M7 31 h3 v1 h-3Z M11 31 h2 v1 h-2Z M15 31 h2 v1 h-2Z M19 31 h1 v1 h-1Z M24 31 h1 v1 h-1Z M31 31 h2 v1 h-2Z M38 31 h3 v1 h-3Z M44 31 h2 v1 h-2Z M47 31 h2 v1 h-2Z M5 32 h2 v1 h-2Z M8 32 h1 v1 h-1Z M13 32 h2 v1 h-2Z M16 32 h1 v1 h-1Z M19 32 h5 v1 h-5Z M25 32 h1 v1 h-1Z M27 32 h1 v1 h-1Z M30 32 h1 v1 h-1Z M32 32 h4 v1 h-4Z M37 32 h1 v1 h-1Z M39 32 h1 v1 h-1Z M42 32 h2 v1 h-2Z M45 32 h1 v1 h-1Z M48 32 h1 v1 h-1Z M7 33 h1 v1 h-1Z M9 33 h1 v1 h-1Z M11 33 h2 v1 h-2Z M15 33 h2 v1 h-2Z M18 33 h6 v1 h-6Z M26 33 h1 v1 h-1Z M28 33 h1 v1 h-1Z M36 33 h1 v1 h-1Z M39 33 h3 v1 h-3Z M45 33 h2 v1 h-2Z M48 33 h1 v1 h-1Z M4 34 h1 v1 h-1Z M6 34 h4 v1 h-4Z M11 34 h1 v1 h-1Z M13 34 h1 v1 h-1Z M15 34 h1 v1 h-1Z M19 34 h2 v1 h-2Z M29 34 h1 v1 h-1Z M31 34 h1 v1 h-1Z M33 34 h1 v1 h-1Z M37 34 h6 v1 h-6Z M46 34 h1 v1 h-1Z M4 35 h1 v1 h-1Z M8 35 h1 v1 h-1Z M12 35 h3 v1 h-3Z M16 35 h2 v1 h-2Z M20 35 h1 v1 h-1Z M22 35 h1 v1 h-1Z M24 35 h3 v1 h-3Z M28 35 h2 v1 h-2Z M31 35 h4 v1 h-4Z M37 35 h3 v1 h-3Z M44 35 h1 v1 h-1Z M46 35 h2 v1 h-2Z M5 36 h3 v1 h-3Z M9 36 h1 v1 h-1Z M11 36 h2 v1 h-2Z M14 36 h1 v1 h-1Z M16 36 h2 v1 h-2Z M19 36 h1 v1 h-1Z M21 36 h2 v1 h-2Z M24 36 h3 v1 h-3Z M28 36 h1 v1 h-1Z M30 36 h6 v1 h-6Z M37 36 h4 v1 h-4Z M42 36 h2 v1 h-2Z M45 36 h1 v1 h-1Z M48 36 h1 v1 h-1Z M5 37 h2 v1 h-2Z M8 37 h2 v1 h-2Z M11 37 h2 v1 h-2Z M14 37 h2 v1 h-2Z M17 37 h1 v1 h-1Z M20 37 h1 v1 h-1Z M23 37 h1 v1 h-1Z M26 37 h2 v1 h-2Z M29 37 h1 v1 h-1Z M31 37 h3 v1 h-3Z M35 37 h2 v1 h-2Z M39 37 h1 v1 h-1Z M43 37 h1 v1 h-1Z M47 37 h1 v1 h-1Z M12 38 h2 v1 h-2Z M15 38 h1 v1 h-1Z M19 38 h2 v1 h-2Z M22 38 h1 v1 h-1Z M24 38 h1 v1 h-1Z M26 38 h4 v1 h-4Z M31 38 h2 v1 h-2Z M34 38 h1 v1 h-1Z M36 38 h2 v1 h-2Z M41 38 h1 v1 h-1Z M43 38 h2 v1 h-2Z M48 38 h1 v1 h-1Z M11 39 h1 v1 h-1Z M13 39 h2 v1 h-2Z M17 39 h4 v1 h-4Z M22 39 h3 v1 h-3Z M26 39 h1 v1 h-1Z M28 39 h4 v1 h-4Z M34 39 h1 v1 h-1Z M37 39 h1 v1 h-1Z M40 39 h1 v1 h-1Z M42 39 h2 v1 h-2Z M45 39 h1 v1 h-1Z M47 39 h1 v1 h-1Z M12 40 h4 v1 h-4Z M17 40 h3 v1 h-3Z M23 40 h1 v1 h-1Z M30 40 h6 v1 h-6Z M37 40 h1 v1 h-1Z M39 40 h1 v1 h-1Z M45 40 h4 v1 h-4Z M17 41 h6 v1 h-6Z M29 41 h3 v1 h-3Z M35 41 h5 v1 h-5Z M46 41 h1 v1 h-1Z M48 41 h1 v1 h-1Z M13 42 h1 v1 h-1Z M16 42 h1 v1 h-1Z M19 42 h4 v1 h-4Z M29 42 h1 v1 h-1Z M31 42 h1 v1 h-1Z M36 42 h2 v1 h-2Z M45 42 h4 v1 h-4Z M20 43 h3 v1 h-3Z M29 43 h1 v1 h-1Z M33 43 h4 v1 h-4Z M38 43 h1 v1 h-1Z M47 43 h1 v1 h-1Z M13 44 h2 v1 h-2Z M16 44 h1 v1 h-1Z M19 44 h3 v1 h-3Z M29 44 h1 v1 h-1Z M31 44 h2 v1 h-2Z M39 44 h1 v1 h-1Z M46 44 h2 v1 h-2Z M13 45 h2 v1 h-2Z M16 45 h3 v1 h-3Z M21 45 h1 v1 h-1Z M24 45 h1 v1 h-1Z M27 45 h2 v1 h-2Z M31 45 h6 v1 h-6Z M38 45 h1 v1 h-1Z M40 45 h4 v1 h-4Z M48 45 h1 v1 h-1Z M13 46 h2 v1 h-2Z M17 46 h2 v1 h-2Z M20 46 h1 v1 h-1Z M24 46 h2 v1 h-2Z M27 46 h1 v1 h-1Z M29 46 h1 v1 h-1Z M31 46 h3 v1 h-3Z M39 46 h1 v1 h-1Z M41 46 h5 v1 h-5Z M14 47 h2 v1 h-2Z M20 47 h1 v1 h-1Z M22 47 h1 v1 h-1Z M24 47 h1 v1 h-1Z M26 47 h3 v1 h-3Z M31 47 h5 v1 h-5Z M37 47 h2 v1 h-2Z M40 47 h1 v1 h-1Z M43 47 h1 v1 h-1Z M45 47 h1 v1 h-1Z M13 48 h1 v1 h-1Z M15 48 h2 v1 h-2Z M18 48 h3 v1 h-3Z M25 48 h6 v1 h-6Z M32 48 h3 v1 h-3Z M36 48 h2 v1 h-2Z M40 48 h2 v1 h-2Z M43 48 h2 v1 h-2Z M47 48 h2 v1 h-2Z " /><path class="qr-6 " stroke="transparent" fill="#fff" fill-opacity="1" d="M5 5 h5 v1 h-5Z M43 5 h5 v1 h-5Z M5 6 h1 v1 h-1Z M9 6 h1 v1 h-1Z M43 6 h1 v1 h-1Z M47 6 h1 v1 h-1Z M5 7 h1 v1 h-1Z M9 7 h1 v1 h-1Z M43 7 h1 v1 h-1Z M47 7 h1 v1 h-1Z M5 8 h1 v1 h-1Z M9 8 h1 v1 h-1Z M43 8 h1 v1 h-1Z M47 8 h1 v1 h-1Z M5 9 h5 v1 h-5Z M43 9 h5 v1 h-5Z M5 43 h5 v1 h-5Z M5 44 h1 v1 h-1Z M9 44 h1 v1 h-1Z M5 45 h1 v1 h-1Z M9 45 h1 v1 h-1Z M5 46 h1 v1 h-1Z M9 46 h1 v1 h-1Z M5 47 h5 v1 h-5Z " /><path class="qr-8 " stroke="transparent" fill="#fff" fill-opacity="1" d="M11 4 h1 v1 h-1Z M41 4 h1 v1 h-1Z M11 5 h1 v1 h-1Z M41 5 h1 v1 h-1Z M11 6 h1 v1 h-1Z M41 6 h1 v1 h-1Z M11 7 h1 v1 h-1Z M41 7 h1 v1 h-1Z M11 8 h1 v1 h-1Z M41 8 h1 v1 h-1Z M11 9 h1 v1 h-1Z M41 9 h1 v1 h-1Z M11 10 h1 v1 h-1Z M41 10 h1 v1 h-1Z M4 11 h8 v1 h-8Z M41 11 h8 v1 h-8Z M4 41 h8 v1 h-8Z M11 42 h1 v1 h-1Z M11 43 h1 v1 h-1Z M11 44 h1 v1 h-1Z M11 45 h1 v1 h-1Z M11 46 h1 v1 h-1Z M11 47 h1 v1 h-1Z M11 48 h1 v1 h-1Z " /><path class="qr-10 " stroke="transparent" fill="#fff" fill-opacity="1" d="M25 9 h3 v1 h-3Z M25 10 h1 v1 h-1Z M27 10 h1 v1 h-1Z M25 11 h3 v1 h-3Z M9 25 h3 v1 h-3Z M25 25 h3 v1 h-3Z M41 25 h3 v1 h-3Z M9 26 h1 v1 h-1Z M11 26 h1 v1 h-1Z M25 26 h1 v1 h-1Z M27 26 h1 v1 h-1Z M41 26 h1 v1 h-1Z M43 26 h1 v1 h-1Z M9 27 h3 v1 h-3Z M25 27 h3 v1 h-3Z M41 27 h3 v1 h-3Z M25 41 h3 v1 h-3Z M41 41 h3 v1 h-3Z M25 42 h1 v1 h-1Z M27 42 h1 v1 h-1Z M41 42 h1 v1 h-1Z M43 42 h1 v1 h-1Z M25 43 h3 v1 h-3Z M41 43 h3 v1 h-3Z " /><path class="qr-12 " stroke="transparent" fill="#fff" fill-opacity="1" d="M13 10 h1 v1 h-1Z M15 10 h1 v1 h-1Z M17 10 h1 v1 h-1Z M19 10 h1 v1 h-1Z M21 10 h1 v1 h-1Z M23 10 h1 v1 h-1Z M29 10 h1 v1 h-1Z M31 10 h1 v1 h-1Z M33 10 h1 v1 h-1Z M35 10 h1 v1 h-1Z M37 10 h1 v1 h-1Z M39 10 h1 v1 h-1Z M10 13 h1 v1 h-1Z M10 15 h1 v1 h-1Z M10 17 h1 v1 h-1Z M10 19 h1 v1 h-1Z M10 21 h1 v1 h-1Z M10 23 h1 v1 h-1Z M10 29 h1 v1 h-1Z M10 31 h1 v1 h-1Z M10 33 h1 v1 h-1Z M10 35 h1 v1 h-1Z M10 37 h1 v1 h-1Z M10 39 h1 v1 h-1Z " /><path class="qr-14 " stroke="transparent" fill="#fff" fill-opacity="1" d="M12 4 h1 v1 h-1Z M12 5 h1 v1 h-1Z M12 8 h1 v1 h-1Z M12 9 h1 v1 h-1Z M12 11 h1 v1 h-1Z M4 12 h3 v1 h-3Z M9 12 h1 v1 h-1Z M12 12 h1 v1 h-1Z M41 12 h4 v1 h-4Z M47 12 h2 v1 h-2Z M12 43 h1 v1 h-1Z M12 46 h1 v1 h-1Z M12 47 h1 v1 h-1Z M12 48 h1 v1 h-1Z " /><path class="qr-16 " stroke="transparent" fill="#fff" fill-opacity="1" d="M38 4 h2 v1 h-2Z M38 5 h1 v1 h-1Z M40 5 h1 v1 h-1Z M38 6 h1 v1 h-1Z M40 6 h1 v1 h-1Z M38 7 h1 v1 h-1Z M38 9 h3 v1 h-3Z M4 38 h4 v1 h-4Z M9 38 h1 v1 h-1Z M4 39 h1 v1 h-1Z M9 39 h1 v1 h-1Z M5 40 h2 v1 h-2Z M9 40 h1 v1 h-1Z " /><path class="qr-18 " stroke="transparent" fill="#fff" fill-opacity="1" d="M0 0 h53 v1 h-53Z M0 1 h53 v1 h-53Z M0 2 h53 v1 h-53Z M0 3 h53 v1 h-53Z M0 4 h4 v1 h-4Z M49 4 h4 v1 h-4Z M0 5 h4 v1 h-4Z M49 5 h4 v1 h-4Z M0 6 h4 v1 h-4Z M49 6 h4 v1 h-4Z M0 7 h4 v1 h-4Z M49 7 h4 v1 h-4Z M0 8 h4 v1 h-4Z M49 8 h4 v1 h-4Z M0 9 h4 v1 h-4Z M49 9 h4 v1 h-4Z M0 10 h4 v1 h-4Z M49 10 h4 v1 h-4Z M0 11 h4 v1 h-4Z M49 11 h4 v1 h-4Z M0 12 h4 v1 h-4Z M49 12 h4 v1 h-4Z M0 13 h4 v1 h-4Z M49 13 h4 v1 h-4Z M0 14 h4 v1 h-4Z M49 14 h4 v1 h-4Z M0 15 h4 v1 h-4Z M49 15 h4 v1 h-4Z M0 16 h4 v1 h-4Z M49 16 h4 v1 h-4Z M0 17 h4 v1 h-4Z M49 17 h4 v1 h-4Z M0 18 h4 v1 h-4Z M49 18 h4 v1 h-4Z M0 19 h4 v1 h-4Z M49 19 h4 v1 h-4Z M0 20 h4 v1 h-4Z M49 20 h4 v1 h-4Z M0 21 h4 v1 h-4Z M49 21 h4 v1 h-4Z M0 22 h4 v1 h-4Z M49 22 h4 v1 h-4Z M0 23 h4 v1 h-4Z M49 23 h4 v1 h-4Z M0 24 h4 v1 h-4Z M49 24 h4 v1 h-4Z M0 25 h4 v1 h-4Z M49 25 h4 v1 h-4Z M0 26 h4 v1 h-4Z M49 26 h4 v1 h-4Z M0 27 h4 v1 h-4Z M49 27 h4 v1 h-4Z M0 28 h4 v1 h-4Z M49 28 h4 v1 h-4Z M0 29 h4 v1 h-4Z M49 29 h4 v1 h-4Z M0 30 h4 v1 h-4Z M49 30 h4 v1 h-4Z M0 31 h4 v1 h-4Z M49 31 h4 v1 h-4Z M0 32 h4 v1 h-4Z M49 32 h4 v1 h-4Z M0 33 h4 v1 h-4Z M49 33 h4 v1 h-4Z M0 34 h4 v1 h-4Z M49 34 h4 v1 h-4Z M0 35 h4 v1 h-4Z M49 35 h4 v1 h-4Z M0 36 h4 v1 h-4Z M49 36 h4 v1 h-4Z M0 37 h4 v1 h-4Z M49 37 h4 v1 h-4Z M0 38 h4 v1 h-4Z M49 38 h4 v1 h-4Z M0 39 h4 v1 h-4Z M49 39 h4 v1 h-4Z M0 40 h4 v1 h-4Z M49 40 h4 v1 h-4Z M0 41 h4 v1 h-4Z M49 41 h4 v1 h-4Z M0 42 h4 v1 h-4Z M49 42 h4 v1 h-4Z M0 43 h4 v1 h-4Z M49 43 h4 v1 h-4Z M0 44 h4 v1 h-4Z M49 44 h4 v1 h-4Z M0 45 h4 v1 h-4Z M49 45 h4 v1 h-4Z M0 46 h4 v1 h-4Z M49 46 h4 v1 h-4Z M0 47 h4 v1 h-4Z M49 47 h4 v1 h-4Z M0 48 h4 v1 h-4Z M49 48 h4 v1 h-4Z M0 49 h53 v1 h-53Z M0 50 h53 v1 h-53Z M0 51 h53 v1 h-53Z M0 52 h53 v1 h-53Z " /><path class="qr-512 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 41 h1 v1 h-1Z " /><path class="qr-1024 " stroke="transparent" fill="#000" fill-opacity="1" d="M13 4 h2 v1 h-2Z M16 4 h2 v1 h-2Z M21 4 h3 v1 h-3Z M25 4 h2 v1 h-2Z M34 4 h1 v1 h-1Z M36 4 h2 v1 h-2Z M13 5 h3 v1 h-3Z M22 5 h3 v1 h-3Z M27 5 h2 v1 h-2Z M33 5 h1 v1 h-1Z M35 5 h1 v1 h-1Z M37 5 h1 v1 h-1Z M18 6 h1 v1 h-1Z M26 6 h4 v1 h-4Z M32 6 h3 v1 h-3Z M37 6 h1 v1 h-1Z M14 7 h1 v1 h-1Z M16 7 h1 v1 h-1Z M18 7 h2 v1 h-2Z M23 7 h2 v1 h-2Z M29 7 h3 v1 h-3Z M33 7 h2 v1 h-2Z M36 7 h1 v1 h-1Z M14 8 h1 v1 h-1Z M16 8 h2 v1 h-2Z M20 8 h2 v1 h-2Z M23 8 h1 v1 h-1Z M30 8 h1 v1 h-1Z M33 8 h5 v1 h-5Z M14 9 h1 v1 h-1Z M16 9 h5 v1 h-5Z M23 9 h1 v1 h-1Z M30 9 h1 v1 h-1Z M32 9 h3 v1 h-3Z M37 9 h1 v1 h-1Z M17 11 h2 v1 h-2Z M23 11 h1 v1 h-1Z M31 11 h3 v1 h-3Z M35 11 h4 v1 h-4Z M40 11 h1 v1 h-1Z M13 12 h4 v1 h-4Z M18 12 h1 v1 h-1Z M20 12 h4 v1 h-4Z M30 12 h2 v1 h-2Z M36 12 h1 v1 h-1Z M40 12 h1 v1 h-1Z M4 13 h1 v1 h-1Z M6 13 h2 v1 h-2Z M9 13 h1 v1 h-1Z M13 13 h2 v1 h-2Z M16 13 h1 v1 h-1Z M19 13 h2 v1 h-2Z M24 13 h10 v1 h-10Z M38 13 h2 v1 h-2Z M41 13 h1 v1 h-1Z M46 13 h1 v1 h-1Z M48 13 h1 v1 h-1Z M7 14 h1 v1 h-1Z M9 14 h1 v1 h-1Z M11 14 h1 v1 h-1Z M15 14 h1 v1 h-1Z M17 14 h1 v1 h-1Z M20 14 h1 v1 h-1Z M22 14 h2 v1 h-2Z M25 14 h5 v1 h-5Z M31 14 h5 v1 h-5Z M37 14 h3 v1 h-3Z M42 14 h1 v1 h-1Z M44 14 h1 v1 h-1Z M46 14 h2 v1 h-2Z M6 15 h2 v1 h-2Z M11 15 h1 v1 h-1Z M13 15 h9 v1 h-9Z M23 15 h1 v1 h-1Z M26 15 h1 v1 h-1Z M30 15 h1 v1 h-1Z M33 15 h3 v1 h-3Z M37 15 h2 v1 h-2Z M43 15 h4 v1 h-4Z M48 15 h1 v1 h-1Z M4 16 h1 v1 h-1Z M6 16 h3 v1 h-3Z M13 16 h1 v1 h-1Z M17 16 h1 v1 h-1Z M23 16 h2 v1 h-2Z M26 16 h1 v1 h-1Z M28 16 h1 v1 h-1Z M31 16 h1 v1 h-1Z M34 16 h3 v1 h-3Z M38 16 h1 v1 h-1Z M40 16 h5 v1 h-5Z M46 16 h1 v1 h-1Z M4 17 h4 v1 h-4Z M9 17 h1 v1 h-1Z M12 17 h1 v1 h-1Z M14 17 h3 v1 h-3Z M18 17 h1 v1 h-1Z M20 17 h2 v1 h-2Z M25 17 h3 v1 h-3Z M30 17 h1 v1 h-1Z M34 17 h1 v1 h-1Z M36 17 h2 v1 h-2Z M40 17 h1 v1 h-1Z M42 17 h2 v1 h-2Z M48 17 h1 v1 h-1Z M4 18 h1 v1 h-1Z M6 18 h3 v1 h-3Z M11 18 h1 v1 h-1Z M14 18 h1 v1 h-1Z M18 18 h2 v1 h-2Z M23 18 h1 v1 h-1Z M26 18 h2 v1 h-2Z M30 18 h1 v1 h-1Z M33 18 h3 v1 h-3Z M37 18 h1 v1 h-1Z M39 18 h2 v1 h-2Z M42 18 h3 v1 h-3Z M46 18 h2 v1 h-2Z M4 19 h2 v1 h-2Z M8 19 h1 v1 h-1Z M12 19 h2 v1 h-2Z M15 19 h1 v1 h-1Z M18 19 h2 v1 h-2Z M22 19 h1 v1 h-1Z M24 19 h1 v1 h-1Z M27 19 h1 v1 h-1Z M29 19 h2 v1 h-2Z M33 19 h1 v1 h-1Z M37 19 h1 v1 h-1Z M40 19 h3 v1 h-3Z M44 19 h5 v1 h-5Z M5 20 h1 v1 h-1Z M8 20 h1 v1 h-1Z M12 20 h4 v1 h-4Z M17 20 h1 v1 h-1Z M24 20 h1 v1 h-1Z M28 20 h1 v1 h-1Z M33 20 h1 v1 h-1Z M35 20 h4 v1 h-4Z M41 20 h2 v1 h-2Z M44 20 h1 v1 h-1Z M48 20 h1 v1 h-1Z M6 21 h4 v1 h-4Z M12 21 h1 v1 h-1Z M14 21 h6 v1 h-6Z M21 21 h2 v1 h-2Z M24 21 h1 v1 h-1Z M27 21 h1 v1 h-1Z M29 21 h1 v1 h-1Z M32 21 h1 v1 h-1Z M37 21 h1 v1 h-1Z M40 21 h1 v1 h-1Z M48 21 h1 v1 h-1Z M5 22 h1 v1 h-1Z M9 22 h1 v1 h-1Z M12 22 h3 v1 h-3Z M17 22 h1 v1 h-1Z M19 22 h2 v1 h-2Z M22 22 h1 v1 h-1Z M26 22 h4 v1 h-4Z M31 22 h1 v1 h-1Z M33 22 h2 v1 h-2Z M36 22 h6 v1 h-6Z M45 22 h2 v1 h-2Z M48 22 h1 v1 h-1Z M4 23 h1 v1 h-1Z M6 23 h1 v1 h-1Z M11 23 h2 v1 h-2Z M15 23 h1 v1 h-1Z M21 23 h2 v1 h-2Z M24 23 h2 v1 h-2Z M27 23 h2 v1 h-2Z M32 23 h1 v1 h-1Z M34 23 h1 v1 h-1Z M41 23 h2 v1 h-2Z M44 23 h1 v1 h-1Z M46 23 h1 v1 h-1Z M48 23 h1 v1 h-1Z M6 24 h1 v1 h-1Z M14 24 h1 v1 h-1Z M16 24 h1 v1 h-1Z M19 24 h4 v1 h-4Z M30 24 h2 v1 h-2Z M33 24 h2 v1 h-2Z M38 24 h1 v1 h-1Z M47 24 h1 v1 h-1Z M4 25 h2 v1 h-2Z M7 25 h1 v1 h-1Z M15 25 h1 v1 h-1Z M18 25 h1 v1 h-1Z M20 25 h1 v1 h-1Z M22 25 h2 v1 h-2Z M30 25 h1 v1 h-1Z M34 25 h3 v1 h-3Z M38 25 h2 v1 h-2Z M45 25 h1 v1 h-1Z M4 26 h2 v1 h-2Z M16 26 h2 v1 h-2Z M19 26 h1 v1 h-1Z M22 26 h2 v1 h-2Z M29 26 h2 v1 h-2Z M32 26 h1 v1 h-1Z M34 26 h1 v1 h-1Z M36 26 h1 v1 h-1Z M39 26 h1 v1 h-1Z M45 26 h1 v1 h-1Z M47 26 h2 v1 h-2Z M4 27 h1 v1 h-1Z M13 27 h3 v1 h-3Z M19 27 h3 v1 h-3Z M23 27 h1 v1 h-1Z M29 27 h1 v1 h-1Z M32 27 h1 v1 h-1Z M37 27 h1 v1 h-1Z M39 27 h1 v1 h-1Z M4 28 h2 v1 h-2Z M13 28 h1 v1 h-1Z M15 28 h1 v1 h-1Z M19 28 h1 v1 h-1Z M21 28 h2 v1 h-2Z M29 28 h2 v1 h-2Z M32 28 h2 v1 h-2Z M37 28 h1 v1 h-1Z M39 28 h1 v1 h-1Z M45 28 h3 v1 h-3Z M4 29 h1 v1 h-1Z M8 29 h1 v1 h-1Z M11 29 h1 v1 h-1Z M13 29 h1 v1 h-1Z M15 29 h1 v1 h-1Z M18 29 h2 v1 h-2Z M21 29 h1 v1 h-1Z M24 29 h1 v1 h-1Z M27 29 h1 v1 h-1Z M29 29 h2 v1 h-2Z M33 29 h1 v1 h-1Z M35 29 h1 v1 h-1Z M37 29 h4 v1 h-4Z M42 29 h2 v1 h-2Z M46 29 h3 v1 h-3Z M4 30 h1 v1 h-1Z M6 30 h1 v1 h-1Z M12 30 h1 v1 h-1Z M14 30 h1 v1 h-1Z M16 30 h2 v1 h-2Z M20 30 h5 v1 h-5Z M31 30 h1 v1 h-1Z M33 30 h2 v1 h-2Z M36 30 h6 v1 h-6Z M44 30 h3 v1 h-3Z M48 30 h1 v1 h-1Z M4 31 h1 v1 h-1Z M6 31 h1 v1 h-1Z M13 31 h2 v1 h-2Z M17 31 h2 v1 h-2Z M20 31 h4 v1 h-4Z M25 31 h6 v1 h-6Z M33 31 h5 v1 h-5Z M41 31 h3 v1 h-3Z M46 31 h1 v1 h-1Z M4 32 h1 v1 h-1Z M7 32 h1 v1 h-1Z M9 32 h1 v1 h-1Z M11 32 h2 v1 h-2Z M15 32 h1 v1 h-1Z M17 32 h2 v1 h-2Z M24 32 h1 v1 h-1Z M26 32 h1 v1 h-1Z M28 32 h2 v1 h-2Z M31 32 h1 v1 h-1Z M36 32 h1 v1 h-1Z M38 32 h1 v1 h-1Z M40 32 h2 v1 h-2Z M44 32 h1 v1 h-1Z M46 32 h2 v1 h-2Z M4 33 h3 v1 h-3Z M8 33 h1 v1 h-1Z M13 33 h2 v1 h-2Z M17 33 h1 v1 h-1Z M24 33 h2 v1 h-2Z M27 33 h1 v1 h-1Z M29 33 h7 v1 h-7Z M37 33 h2 v1 h-2Z M42 33 h3 v1 h-3Z M47 33 h1 v1 h-1Z M5 34 h1 v1 h-1Z M12 34 h1 v1 h-1Z M14 34 h1 v1 h-1Z M16 34 h3 v1 h-3Z M21 34 h8 v1 h-8Z M30 34 h1 v1 h-1Z M32 34 h1 v1 h-1Z M34 34 h3 v1 h-3Z M43 34 h3 v1 h-3Z M47 34 h2 v1 h-2Z M5 35 h3 v1 h-3Z M9 35 h1 v1 h-1Z M11 35 h1 v1 h-1Z M15 35 h1 v1 h-1Z M18 35 h2 v1 h-2Z M21 35 h1 v1 h-1Z M23 35 h1 v1 h-1Z M27 35 h1 v1 h-1Z M30 35 h1 v1 h-1Z M35 35 h2 v1 h-2Z M40 35 h4 v1 h-4Z M45 35 h1 v1 h-1Z M48 35 h1 v1 h-1Z M4 36 h1 v1 h-1Z M8 36 h1 v1 h-1Z M13 36 h1 v1 h-1Z M15 36 h1 v1 h-1Z M18 36 h1 v1 h-1Z M20 36 h1 v1 h-1Z M23 36 h1 v1 h-1Z M27 36 h1 v1 h-1Z M29 36 h1 v1 h-1Z M36 36 h1 v1 h-1Z M41 36 h1 v1 h-1Z M44 36 h1 v1 h-1Z M46 36 h2 v1 h-2Z M4 37 h1 v1 h-1Z M7 37 h1 v1 h-1Z M13 37 h1 v1 h-1Z M16 37 h1 v1 h-1Z M18 37 h2 v1 h-2Z M21 37 h2 v1 h-2Z M24 37 h2 v1 h-2Z M28 37 h1 v1 h-1Z M30 37 h1 v1 h-1Z M34 37 h1 v1 h-1Z M37 37 h2 v1 h-2Z M40 37 h3 v1 h-3Z M44 37 h3 v1 h-3Z M48 37 h1 v1 h-1Z M11 38 h1 v1 h-1Z M14 38 h1 v1 h-1Z M16 38 h3 v1 h-3Z M21 38 h1 v1 h-1Z M23 38 h1 v1 h-1Z M25 38 h1 v1 h-1Z M30 38 h1 v1 h-1Z M33 38 h1 v1 h-1Z M35 38 h1 v1 h-1Z M38 38 h3 v1 h-3Z M42 38 h1 v1 h-1Z M45 38 h3 v1 h-3Z M12 39 h1 v1 h-1Z M15 39 h2 v1 h-2Z M21 39 h1 v1 h-1Z M25 39 h1 v1 h-1Z M27 39 h1 v1 h-1Z M32 39 h2 v1 h-2Z M35 39 h2 v1 h-2Z M38 39 h2 v1 h-2Z M41 39 h1 v1 h-1Z M44 39 h1 v1 h-1Z M46 39 h1 v1 h-1Z M48 39 h1 v1 h-1Z M11 40 h1 v1 h-1Z M16 40 h1 v1 h-1Z M20 40 h3 v1 h-3Z M29 40 h1 v1 h-1Z M36 40 h1 v1 h-1Z M38 40 h1 v1 h-1Z M13 41 h4 v1 h-4Z M23 41 h1 v1 h-1Z M32 41 h3 v1 h-3Z M45 41 h1 v1 h-1Z M47 41 h1 v1 h-1Z M14 42 h2 v1 h-2Z M17 42 h2 v1 h-2Z M23 42 h1 v1 h-1Z M30 42 h1 v1 h-1Z M32 42 h4 v1 h-4Z M38 42 h2 v1 h-2Z M13 43 h7 v1 h-7Z M23 43 h1 v1 h-1Z M30 43 h3 v1 h-3Z M37 43 h1 v1 h-1Z M39 43 h1 v1 h-1Z M45 43 h2 v1 h-2Z M48 43 h1 v1 h-1Z M15 44 h1 v1 h-1Z M17 44 h2 v1 h-2Z M22 44 h2 v1 h-2Z M30 44 h1 v1 h-1Z M33 44 h6 v1 h-6Z M45 44 h1 v1 h-1Z M48 44 h1 v1 h-1Z M15 45 h1 v1 h-1Z M19 45 h2 v1 h-2Z M22 45 h2 v1 h-2Z M25 45 h2 v1 h-2Z M29 45 h2 v1 h-2Z M37 45 h1 v1 h-1Z M39 45 h1 v1 h-1Z M44 45 h4 v1 h-4Z M15 46 h2 v1 h-2Z M19 46 h1 v1 h-1Z M21 46 h3 v1 h-3Z M26 46 h1 v1 h-1Z M28 46 h1 v1 h-1Z M30 46 h1 v1 h-1Z M34 46 h5 v1 h-5Z M40 46 h1 v1 h-1Z M46 46 h3 v1 h-3Z M13 47 h1 v1 h-1Z M16 47 h4 v1 h-4Z M21 47 h1 v1 h-1Z M23 47 h1 v1 h-1Z M25 47 h1 v1 h-1Z M29 47 h2 v1 h-2Z M36 47 h1 v1 h-1Z M39 47 h1 v1 h-1Z M41 47 h2 v1 h-2Z M44 47 h1 v1 h-1Z M46 47 h3 v1 h-3Z M14 48 h1 v1 h-1Z M17 48 h1 v1 h-1Z M21 48 h4 v1 h-4Z M31 48 h1 v1 h-1Z M35 48 h1 v1 h-1Z M38 48 h2 v1 h-2Z M42 48 h1 v1 h-1Z M45 48 h2 v1 h-2Z " /><path class="qr-1536 " stroke="transparent" fill="#000" fill-opacity="1" d="M4 4 h7 v1 h-7Z M42 4 h7 v1 h-7Z M4 5 h1 v1 h-1Z M10 5 h1 v1 h-1Z M42 5 h1 v1 h-1Z M48 5 h1 v1 h-1Z M4 6 h1 v1 h-1Z M10 6 h1 v1 h-1Z M42 6 h1 v1 h-1Z M48 6 h1 v1 h-1Z M4 7 h1 v1 h-1Z M10 7 h1 v1 h-1Z M42 7 h1 v1 h-1Z M48 7 h1 v1 h-1Z M4 8 h1 v1 h-1Z M10 8 h1 v1 h-1Z M42 8 h1 v1 h-1Z M48 8 h1 v1 h-1Z M4 9 h1 v1 h-1Z M10 9 h1 v1 h-1Z M42 9 h1 v1 h-1Z M48 9 h1 v1 h-1Z M4 10 h7 v1 h-7Z M42 10 h7 v1 h-7Z M4 42 h7 v1 h-7Z M4 43 h1 v1 h-1Z M10 43 h1 v1 h-1Z M4 44 h1 v1 h-1Z M10 44 h1 v1 h-1Z M4 45 h1 v1 h-1Z M10 45 h1 v1 h-1Z M4 46 h1 v1 h-1Z M10 46 h1 v1 h-1Z M4 47 h1 v1 h-1Z M10 47 h1 v1 h-1Z M4 48 h7 v1 h-7Z " /><path class="qr-2560 " stroke="transparent" fill="#000" fill-opacity="1" d="M24 8 h5 v1 h-5Z M24 9 h1 v1 h-1Z M28 9 h1 v1 h-1Z M24 10 h1 v1 h-1Z M26 10 h1 v1 h-1Z M28 10 h1 v1 h-1Z M24 11 h1 v1 h-1Z M28 11 h1 v1 h-1Z M24 12 h5 v1 h-5Z M8 24 h5 v1 h-5Z M24 24 h5 v1 h-5Z M40 24 h5 v1 h-5Z M8 25 h1 v1 h-1Z M12 25 h1 v1 h-1Z M24 25 h1 v1 h-1Z M28 25 h1 v1 h-1Z M40 25 h1 v1 h-1Z M44 25 h1 v1 h-1Z M8 26 h1 v1 h-1Z M10 26 h1 v1 h-1Z M12 26 h1 v1 h-1Z M24 26 h1 v1 h-1Z M26 26 h1 v1 h-1Z M28 26 h1 v1 h-1Z M40 26 h1 v1 h-1Z M42 26 h1 v1 h-1Z M44 26 h1 v1 h-1Z M8 27 h1 v1 h-1Z M12 27 h1 v1 h-1Z M24 27 h1 v1 h-1Z M28 27 h1 v1 h-1Z M40 27 h1 v1 h-1Z M44 27 h1 v1 h-1Z M8 28 h5 v1 h-5Z M24 28 h5 v1 h-5Z M40 28 h5 v1 h-5Z M24 40 h5 v1 h-5Z M40 40 h5 v1 h-5Z M24 41 h1 v1 h-1Z M28 41 h1 v1 h-1Z M40 41 h1 v1 h-1Z M44 41 h1 v1 h-1Z M24 42 h1 v1 h-1Z M26 42 h1 v1 h-1Z M28 42 h1 v1 h-1Z M40 42 h1 v1 h-1Z M42 42 h1 v1 h-1Z M44 42 h1 v1 h-1Z M24 43 h1 v1 h-1Z M28 43 h1 v1 h-1Z M40 43 h1 v1 h-1Z M44 43 h1 v1 h-1Z M24 44 h5 v1 h-5Z M40 44 h5 v1 h-5Z " /><path class="qr-3072 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 10 h1 v1 h-1Z M14 10 h1 v1 h-1Z M16 10 h1 v1 h-1Z M18 10 h1 v1 h-1Z M20 10 h1 v1 h-1Z M22 10 h1 v1 h-1Z M30 10 h1 v1 h-1Z M32 10 h1 v1 h-1Z M34 10 h1 v1 h-1Z M36 10 h1 v1 h-1Z M38 10 h1 v1 h-1Z M40 10 h1 v1 h-1Z M10 12 h1 v1 h-1Z M10 14 h1 v1 h-1Z M10 16 h1 v1 h-1Z M10 18 h1 v1 h-1Z M10 20 h1 v1 h-1Z M10 22 h1 v1 h-1Z M10 30 h1 v1 h-1Z M10 32 h1 v1 h-1Z M10 34 h1 v1 h-1Z M10 36 h1 v1 h-1Z M10 38 h1 v1 h-1Z M10 40 h1 v1 h-1Z " /><path class="qr-3584 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 6 h1 v1 h-1Z M12 7 h1 v1 h-1Z M7 12 h2 v1 h-2Z M11 12 h1 v1 h-1Z M45 12 h2 v1 h-2Z M12 42 h1 v1 h-1Z M12 44 h1 v1 h-1Z M12 45 h1 v1 h-1Z " /><path class="qr-4096 " stroke="transparent" fill="#000" fill-opacity="1" d="M40 4 h1 v1 h-1Z M39 5 h1 v1 h-1Z M39 6 h1 v1 h-1Z M39 7 h2 v1 h-2Z M38 8 h3 v1 h-3Z M8 38 h1 v1 h-1Z M5 39 h4 v1 h-4Z M4 40 h1 v1 h-1Z M7 40 h2 v1 h-2Z " /><path class="qr-5632 " stroke="transparent" fill="#000" fill-opacity="1" d="M6 6 h3 v1 h-3Z M44 6 h3 v1 h-3Z M6 7 h3 v1 h-3Z M44 7 h3 v1 h-3Z M6 8 h3 v1 h-3Z M44 8 h3 v1 h-3Z M6 44 h3 v1 h-3Z M6 45 h3 v1 h-3Z M6 46 h3 v1 h-3Z " /></svg>

    </a>
    <figcaption aria-hidden="true" class="hidden" hidden>Un don Paypal pour Stéphane HUC</figcaption>
</figure>


<h3 id="tipeee">Tip<em>eee</em></h3>
<ul>
<li><a href="https://fr.tipeee.com/hucste" rel="external">https://fr.tipeee.com/hucste</a></li>
</ul>


<figure class="pure-img">
    <a href="/svg/qrcode/tipee.svg" title="Un soutien tipeee pour Stéphane HUC">
    <svg xmlns="http://www.w3.org/2000/svg" height="128" viewBox="0 0 53 53" width="128">
<defs><style>rect{shape-rendering:crispEdges}</style></defs>
<path class="qr-4 " stroke="transparent" fill="#fff" fill-opacity="1" d="M14 4 h1 v1 h-1Z M16 4 h1 v1 h-1Z M18 4 h1 v1 h-1Z M20 4 h1 v1 h-1Z M22 4 h2 v1 h-2Z M25 4 h1 v1 h-1Z M27 4 h4 v1 h-4Z M35 4 h2 v1 h-2Z M17 5 h5 v1 h-5Z M23 5 h1 v1 h-1Z M27 5 h1 v1 h-1Z M32 5 h2 v1 h-2Z M35 5 h1 v1 h-1Z M13 6 h1 v1 h-1Z M15 6 h3 v1 h-3Z M19 6 h1 v1 h-1Z M22 6 h2 v1 h-2Z M25 6 h1 v1 h-1Z M29 6 h1 v1 h-1Z M31 6 h1 v1 h-1Z M35 6 h1 v1 h-1Z M13 7 h1 v1 h-1Z M15 7 h1 v1 h-1Z M17 7 h1 v1 h-1Z M19 7 h1 v1 h-1Z M21 7 h2 v1 h-2Z M26 7 h3 v1 h-3Z M31 7 h1 v1 h-1Z M33 7 h3 v1 h-3Z M37 7 h1 v1 h-1Z M13 8 h3 v1 h-3Z M17 8 h1 v1 h-1Z M23 8 h1 v1 h-1Z M30 8 h2 v1 h-2Z M35 8 h3 v1 h-3Z M14 9 h3 v1 h-3Z M19 9 h1 v1 h-1Z M22 9 h2 v1 h-2Z M29 9 h2 v1 h-2Z M32 9 h1 v1 h-1Z M35 9 h1 v1 h-1Z M13 11 h1 v1 h-1Z M15 11 h2 v1 h-2Z M20 11 h1 v1 h-1Z M23 11 h1 v1 h-1Z M30 11 h1 v1 h-1Z M32 11 h1 v1 h-1Z M34 11 h4 v1 h-4Z M39 11 h1 v1 h-1Z M13 12 h1 v1 h-1Z M16 12 h1 v1 h-1Z M19 12 h1 v1 h-1Z M21 12 h3 v1 h-3Z M31 12 h2 v1 h-2Z M35 12 h1 v1 h-1Z M38 12 h1 v1 h-1Z M4 13 h1 v1 h-1Z M6 13 h2 v1 h-2Z M11 13 h3 v1 h-3Z M15 13 h2 v1 h-2Z M23 13 h1 v1 h-1Z M26 13 h2 v1 h-2Z M30 13 h1 v1 h-1Z M34 13 h3 v1 h-3Z M38 13 h1 v1 h-1Z M40 13 h1 v1 h-1Z M42 13 h4 v1 h-4Z M47 13 h2 v1 h-2Z M4 14 h4 v1 h-4Z M9 14 h1 v1 h-1Z M12 14 h2 v1 h-2Z M15 14 h3 v1 h-3Z M19 14 h3 v1 h-3Z M23 14 h3 v1 h-3Z M28 14 h3 v1 h-3Z M32 14 h1 v1 h-1Z M35 14 h1 v1 h-1Z M37 14 h2 v1 h-2Z M43 14 h1 v1 h-1Z M45 14 h3 v1 h-3Z M5 15 h1 v1 h-1Z M9 15 h1 v1 h-1Z M14 15 h2 v1 h-2Z M17 15 h2 v1 h-2Z M20 15 h2 v1 h-2Z M24 15 h4 v1 h-4Z M30 15 h1 v1 h-1Z M33 15 h1 v1 h-1Z M36 15 h2 v1 h-2Z M40 15 h1 v1 h-1Z M42 15 h1 v1 h-1Z M44 15 h2 v1 h-2Z M47 15 h2 v1 h-2Z M4 16 h2 v1 h-2Z M7 16 h1 v1 h-1Z M13 16 h1 v1 h-1Z M20 16 h1 v1 h-1Z M22 16 h2 v1 h-2Z M25 16 h2 v1 h-2Z M29 16 h1 v1 h-1Z M33 16 h2 v1 h-2Z M36 16 h1 v1 h-1Z M38 16 h2 v1 h-2Z M41 16 h1 v1 h-1Z M44 16 h2 v1 h-2Z M47 16 h1 v1 h-1Z M4 17 h1 v1 h-1Z M9 17 h1 v1 h-1Z M12 17 h3 v1 h-3Z M16 17 h1 v1 h-1Z M18 17 h2 v1 h-2Z M24 17 h2 v1 h-2Z M29 17 h2 v1 h-2Z M32 17 h2 v1 h-2Z M37 17 h3 v1 h-3Z M41 17 h2 v1 h-2Z M47 17 h1 v1 h-1Z M6 18 h1 v1 h-1Z M9 18 h1 v1 h-1Z M12 18 h1 v1 h-1Z M14 18 h1 v1 h-1Z M16 18 h1 v1 h-1Z M18 18 h2 v1 h-2Z M21 18 h2 v1 h-2Z M24 18 h2 v1 h-2Z M27 18 h3 v1 h-3Z M31 18 h3 v1 h-3Z M36 18 h5 v1 h-5Z M42 18 h1 v1 h-1Z M44 18 h2 v1 h-2Z M5 19 h2 v1 h-2Z M11 19 h1 v1 h-1Z M13 19 h1 v1 h-1Z M16 19 h5 v1 h-5Z M23 19 h6 v1 h-6Z M30 19 h1 v1 h-1Z M34 19 h2 v1 h-2Z M38 19 h2 v1 h-2Z M41 19 h2 v1 h-2Z M44 19 h4 v1 h-4Z M5 20 h1 v1 h-1Z M11 20 h1 v1 h-1Z M13 20 h1 v1 h-1Z M15 20 h3 v1 h-3Z M20 20 h1 v1 h-1Z M22 20 h1 v1 h-1Z M24 20 h2 v1 h-2Z M28 20 h4 v1 h-4Z M39 20 h2 v1 h-2Z M43 20 h1 v1 h-1Z M46 20 h2 v1 h-2Z M6 21 h2 v1 h-2Z M11 21 h4 v1 h-4Z M16 21 h1 v1 h-1Z M20 21 h1 v1 h-1Z M22 21 h2 v1 h-2Z M25 21 h1 v1 h-1Z M27 21 h1 v1 h-1Z M29 21 h3 v1 h-3Z M34 21 h1 v1 h-1Z M36 21 h1 v1 h-1Z M38 21 h3 v1 h-3Z M42 21 h2 v1 h-2Z M46 21 h2 v1 h-2Z M5 22 h1 v1 h-1Z M8 22 h2 v1 h-2Z M12 22 h2 v1 h-2Z M15 22 h1 v1 h-1Z M18 22 h1 v1 h-1Z M21 22 h4 v1 h-4Z M27 22 h1 v1 h-1Z M29 22 h1 v1 h-1Z M35 22 h2 v1 h-2Z M40 22 h3 v1 h-3Z M44 22 h2 v1 h-2Z M9 23 h1 v1 h-1Z M16 23 h1 v1 h-1Z M18 23 h2 v1 h-2Z M21 23 h1 v1 h-1Z M23 23 h2 v1 h-2Z M27 23 h2 v1 h-2Z M32 23 h2 v1 h-2Z M37 23 h1 v1 h-1Z M40 23 h2 v1 h-2Z M45 23 h4 v1 h-4Z M7 24 h1 v1 h-1Z M15 24 h1 v1 h-1Z M18 24 h5 v1 h-5Z M30 24 h1 v1 h-1Z M33 24 h3 v1 h-3Z M37 24 h3 v1 h-3Z M45 24 h4 v1 h-4Z M5 25 h1 v1 h-1Z M7 25 h1 v1 h-1Z M17 25 h1 v1 h-1Z M19 25 h2 v1 h-2Z M23 25 h1 v1 h-1Z M29 25 h3 v1 h-3Z M33 25 h1 v1 h-1Z M37 25 h1 v1 h-1Z M39 25 h1 v1 h-1Z M45 25 h2 v1 h-2Z M4 26 h1 v1 h-1Z M7 26 h1 v1 h-1Z M14 26 h1 v1 h-1Z M23 26 h1 v1 h-1Z M30 26 h1 v1 h-1Z M33 26 h1 v1 h-1Z M35 26 h1 v1 h-1Z M37 26 h1 v1 h-1Z M39 26 h1 v1 h-1Z M45 26 h1 v1 h-1Z M6 27 h1 v1 h-1Z M13 27 h1 v1 h-1Z M16 27 h1 v1 h-1Z M20 27 h4 v1 h-4Z M29 27 h1 v1 h-1Z M33 27 h1 v1 h-1Z M35 27 h2 v1 h-2Z M38 27 h1 v1 h-1Z M45 27 h4 v1 h-4Z M4 28 h4 v1 h-4Z M13 28 h5 v1 h-5Z M20 28 h2 v1 h-2Z M30 28 h2 v1 h-2Z M35 28 h1 v1 h-1Z M39 28 h1 v1 h-1Z M45 28 h2 v1 h-2Z M48 28 h1 v1 h-1Z M4 29 h1 v1 h-1Z M6 29 h2 v1 h-2Z M9 29 h1 v1 h-1Z M14 29 h2 v1 h-2Z M17 29 h2 v1 h-2Z M24 29 h6 v1 h-6Z M31 29 h6 v1 h-6Z M38 29 h3 v1 h-3Z M43 29 h3 v1 h-3Z M47 29 h2 v1 h-2Z M7 30 h2 v1 h-2Z M11 30 h1 v1 h-1Z M13 30 h1 v1 h-1Z M15 30 h1 v1 h-1Z M19 30 h2 v1 h-2Z M23 30 h3 v1 h-3Z M27 30 h2 v1 h-2Z M30 30 h3 v1 h-3Z M35 30 h1 v1 h-1Z M40 30 h1 v1 h-1Z M42 30 h1 v1 h-1Z M45 30 h3 v1 h-3Z M4 31 h1 v1 h-1Z M7 31 h1 v1 h-1Z M9 31 h1 v1 h-1Z M13 31 h1 v1 h-1Z M17 31 h1 v1 h-1Z M19 31 h1 v1 h-1Z M23 31 h1 v1 h-1Z M26 31 h1 v1 h-1Z M28 31 h4 v1 h-4Z M33 31 h1 v1 h-1Z M36 31 h2 v1 h-2Z M40 31 h1 v1 h-1Z M42 31 h4 v1 h-4Z M47 31 h2 v1 h-2Z M5 32 h1 v1 h-1Z M8 32 h2 v1 h-2Z M13 32 h1 v1 h-1Z M16 32 h1 v1 h-1Z M18 32 h1 v1 h-1Z M21 32 h1 v1 h-1Z M23 32 h2 v1 h-2Z M26 32 h4 v1 h-4Z M33 32 h2 v1 h-2Z M36 32 h1 v1 h-1Z M38 32 h4 v1 h-4Z M44 32 h2 v1 h-2Z M47 32 h1 v1 h-1Z M4 33 h2 v1 h-2Z M7 33 h1 v1 h-1Z M9 33 h1 v1 h-1Z M13 33 h2 v1 h-2Z M16 33 h2 v1 h-2Z M19 33 h1 v1 h-1Z M21 33 h1 v1 h-1Z M23 33 h2 v1 h-2Z M26 33 h1 v1 h-1Z M28 33 h1 v1 h-1Z M30 33 h2 v1 h-2Z M33 33 h1 v1 h-1Z M37 33 h2 v1 h-2Z M40 33 h5 v1 h-5Z M46 33 h1 v1 h-1Z M48 33 h1 v1 h-1Z M5 34 h5 v1 h-5Z M12 34 h1 v1 h-1Z M19 34 h2 v1 h-2Z M23 34 h1 v1 h-1Z M25 34 h1 v1 h-1Z M28 34 h1 v1 h-1Z M31 34 h1 v1 h-1Z M33 34 h1 v1 h-1Z M36 34 h4 v1 h-4Z M41 34 h1 v1 h-1Z M43 34 h1 v1 h-1Z M48 34 h1 v1 h-1Z M4 35 h1 v1 h-1Z M6 35 h1 v1 h-1Z M8 35 h2 v1 h-2Z M13 35 h2 v1 h-2Z M16 35 h5 v1 h-5Z M23 35 h5 v1 h-5Z M30 35 h1 v1 h-1Z M32 35 h6 v1 h-6Z M41 35 h4 v1 h-4Z M46 35 h1 v1 h-1Z M5 36 h2 v1 h-2Z M8 36 h2 v1 h-2Z M12 36 h1 v1 h-1Z M15 36 h1 v1 h-1Z M20 36 h1 v1 h-1Z M22 36 h3 v1 h-3Z M27 36 h2 v1 h-2Z M32 36 h2 v1 h-2Z M35 36 h1 v1 h-1Z M42 36 h2 v1 h-2Z M48 36 h1 v1 h-1Z M5 37 h2 v1 h-2Z M11 37 h1 v1 h-1Z M13 37 h2 v1 h-2Z M17 37 h4 v1 h-4Z M24 37 h1 v1 h-1Z M26 37 h2 v1 h-2Z M30 37 h1 v1 h-1Z M33 37 h1 v1 h-1Z M35 37 h2 v1 h-2Z M38 37 h2 v1 h-2Z M43 37 h1 v1 h-1Z M45 37 h3 v1 h-3Z M11 38 h9 v1 h-9Z M23 38 h3 v1 h-3Z M27 38 h4 v1 h-4Z M33 38 h3 v1 h-3Z M37 38 h2 v1 h-2Z M40 38 h1 v1 h-1Z M42 38 h4 v1 h-4Z M11 39 h1 v1 h-1Z M13 39 h3 v1 h-3Z M18 39 h5 v1 h-5Z M24 39 h3 v1 h-3Z M30 39 h1 v1 h-1Z M37 39 h1 v1 h-1Z M40 39 h1 v1 h-1Z M42 39 h2 v1 h-2Z M45 39 h3 v1 h-3Z M12 40 h4 v1 h-4Z M18 40 h1 v1 h-1Z M20 40 h3 v1 h-3Z M32 40 h3 v1 h-3Z M37 40 h3 v1 h-3Z M46 40 h2 v1 h-2Z M13 41 h5 v1 h-5Z M32 41 h1 v1 h-1Z M34 41 h2 v1 h-2Z M37 41 h1 v1 h-1Z M39 41 h1 v1 h-1Z M45 41 h2 v1 h-2Z M13 42 h1 v1 h-1Z M15 42 h2 v1 h-2Z M20 42 h2 v1 h-2Z M29 42 h6 v1 h-6Z M36 42 h2 v1 h-2Z M39 42 h1 v1 h-1Z M18 43 h5 v1 h-5Z M30 43 h1 v1 h-1Z M33 43 h1 v1 h-1Z M35 43 h1 v1 h-1Z M38 43 h1 v1 h-1Z M45 43 h2 v1 h-2Z M48 43 h1 v1 h-1Z M13 44 h2 v1 h-2Z M16 44 h1 v1 h-1Z M18 44 h1 v1 h-1Z M20 44 h3 v1 h-3Z M29 44 h2 v1 h-2Z M32 44 h3 v1 h-3Z M39 44 h1 v1 h-1Z M45 44 h2 v1 h-2Z M13 45 h3 v1 h-3Z M17 45 h1 v1 h-1Z M19 45 h2 v1 h-2Z M22 45 h2 v1 h-2Z M26 45 h5 v1 h-5Z M32 45 h1 v1 h-1Z M38 45 h1 v1 h-1Z M42 45 h7 v1 h-7Z M13 46 h2 v1 h-2Z M18 46 h1 v1 h-1Z M20 46 h1 v1 h-1Z M22 46 h1 v1 h-1Z M25 46 h1 v1 h-1Z M27 46 h1 v1 h-1Z M29 46 h2 v1 h-2Z M42 46 h2 v1 h-2Z M47 46 h1 v1 h-1Z M13 47 h1 v1 h-1Z M15 47 h1 v1 h-1Z M18 47 h1 v1 h-1Z M20 47 h1 v1 h-1Z M22 47 h4 v1 h-4Z M29 47 h3 v1 h-3Z M33 47 h2 v1 h-2Z M36 47 h2 v1 h-2Z M42 47 h3 v1 h-3Z M46 47 h1 v1 h-1Z M48 47 h1 v1 h-1Z M13 48 h5 v1 h-5Z M19 48 h2 v1 h-2Z M22 48 h1 v1 h-1Z M25 48 h3 v1 h-3Z M30 48 h5 v1 h-5Z M36 48 h3 v1 h-3Z M40 48 h1 v1 h-1Z M42 48 h2 v1 h-2Z M45 48 h2 v1 h-2Z " /><path class="qr-6 " stroke="transparent" fill="#fff" fill-opacity="1" d="M5 5 h5 v1 h-5Z M43 5 h5 v1 h-5Z M5 6 h1 v1 h-1Z M9 6 h1 v1 h-1Z M43 6 h1 v1 h-1Z M47 6 h1 v1 h-1Z M5 7 h1 v1 h-1Z M9 7 h1 v1 h-1Z M43 7 h1 v1 h-1Z M47 7 h1 v1 h-1Z M5 8 h1 v1 h-1Z M9 8 h1 v1 h-1Z M43 8 h1 v1 h-1Z M47 8 h1 v1 h-1Z M5 9 h5 v1 h-5Z M43 9 h5 v1 h-5Z M5 43 h5 v1 h-5Z M5 44 h1 v1 h-1Z M9 44 h1 v1 h-1Z M5 45 h1 v1 h-1Z M9 45 h1 v1 h-1Z M5 46 h1 v1 h-1Z M9 46 h1 v1 h-1Z M5 47 h5 v1 h-5Z " /><path class="qr-8 " stroke="transparent" fill="#fff" fill-opacity="1" d="M11 4 h1 v1 h-1Z M41 4 h1 v1 h-1Z M11 5 h1 v1 h-1Z M41 5 h1 v1 h-1Z M11 6 h1 v1 h-1Z M41 6 h1 v1 h-1Z M11 7 h1 v1 h-1Z M41 7 h1 v1 h-1Z M11 8 h1 v1 h-1Z M41 8 h1 v1 h-1Z M11 9 h1 v1 h-1Z M41 9 h1 v1 h-1Z M11 10 h1 v1 h-1Z M41 10 h1 v1 h-1Z M4 11 h8 v1 h-8Z M41 11 h8 v1 h-8Z M4 41 h8 v1 h-8Z M11 42 h1 v1 h-1Z M11 43 h1 v1 h-1Z M11 44 h1 v1 h-1Z M11 45 h1 v1 h-1Z M11 46 h1 v1 h-1Z M11 47 h1 v1 h-1Z M11 48 h1 v1 h-1Z " /><path class="qr-10 " stroke="transparent" fill="#fff" fill-opacity="1" d="M25 9 h3 v1 h-3Z M25 10 h1 v1 h-1Z M27 10 h1 v1 h-1Z M25 11 h3 v1 h-3Z M9 25 h3 v1 h-3Z M25 25 h3 v1 h-3Z M41 25 h3 v1 h-3Z M9 26 h1 v1 h-1Z M11 26 h1 v1 h-1Z M25 26 h1 v1 h-1Z M27 26 h1 v1 h-1Z M41 26 h1 v1 h-1Z M43 26 h1 v1 h-1Z M9 27 h3 v1 h-3Z M25 27 h3 v1 h-3Z M41 27 h3 v1 h-3Z M25 41 h3 v1 h-3Z M41 41 h3 v1 h-3Z M25 42 h1 v1 h-1Z M27 42 h1 v1 h-1Z M41 42 h1 v1 h-1Z M43 42 h1 v1 h-1Z M25 43 h3 v1 h-3Z M41 43 h3 v1 h-3Z " /><path class="qr-12 " stroke="transparent" fill="#fff" fill-opacity="1" d="M13 10 h1 v1 h-1Z M15 10 h1 v1 h-1Z M17 10 h1 v1 h-1Z M19 10 h1 v1 h-1Z M21 10 h1 v1 h-1Z M23 10 h1 v1 h-1Z M29 10 h1 v1 h-1Z M31 10 h1 v1 h-1Z M33 10 h1 v1 h-1Z M35 10 h1 v1 h-1Z M37 10 h1 v1 h-1Z M39 10 h1 v1 h-1Z M10 13 h1 v1 h-1Z M10 15 h1 v1 h-1Z M10 17 h1 v1 h-1Z M10 19 h1 v1 h-1Z M10 21 h1 v1 h-1Z M10 23 h1 v1 h-1Z M10 29 h1 v1 h-1Z M10 31 h1 v1 h-1Z M10 33 h1 v1 h-1Z M10 35 h1 v1 h-1Z M10 37 h1 v1 h-1Z M10 39 h1 v1 h-1Z " /><path class="qr-14 " stroke="transparent" fill="#fff" fill-opacity="1" d="M12 5 h1 v1 h-1Z M12 6 h1 v1 h-1Z M12 8 h1 v1 h-1Z M12 9 h1 v1 h-1Z M12 11 h1 v1 h-1Z M4 12 h2 v1 h-2Z M7 12 h1 v1 h-1Z M11 12 h1 v1 h-1Z M42 12 h3 v1 h-3Z M46 12 h2 v1 h-2Z M12 42 h1 v1 h-1Z M12 45 h1 v1 h-1Z M12 47 h1 v1 h-1Z M12 48 h1 v1 h-1Z " /><path class="qr-16 " stroke="transparent" fill="#fff" fill-opacity="1" d="M38 4 h2 v1 h-2Z M38 5 h1 v1 h-1Z M40 5 h1 v1 h-1Z M38 6 h1 v1 h-1Z M40 6 h1 v1 h-1Z M38 7 h1 v1 h-1Z M38 9 h3 v1 h-3Z M4 38 h4 v1 h-4Z M9 38 h1 v1 h-1Z M4 39 h1 v1 h-1Z M9 39 h1 v1 h-1Z M5 40 h2 v1 h-2Z M9 40 h1 v1 h-1Z " /><path class="qr-18 " stroke="transparent" fill="#fff" fill-opacity="1" d="M0 0 h53 v1 h-53Z M0 1 h53 v1 h-53Z M0 2 h53 v1 h-53Z M0 3 h53 v1 h-53Z M0 4 h4 v1 h-4Z M49 4 h4 v1 h-4Z M0 5 h4 v1 h-4Z M49 5 h4 v1 h-4Z M0 6 h4 v1 h-4Z M49 6 h4 v1 h-4Z M0 7 h4 v1 h-4Z M49 7 h4 v1 h-4Z M0 8 h4 v1 h-4Z M49 8 h4 v1 h-4Z M0 9 h4 v1 h-4Z M49 9 h4 v1 h-4Z M0 10 h4 v1 h-4Z M49 10 h4 v1 h-4Z M0 11 h4 v1 h-4Z M49 11 h4 v1 h-4Z M0 12 h4 v1 h-4Z M49 12 h4 v1 h-4Z M0 13 h4 v1 h-4Z M49 13 h4 v1 h-4Z M0 14 h4 v1 h-4Z M49 14 h4 v1 h-4Z M0 15 h4 v1 h-4Z M49 15 h4 v1 h-4Z M0 16 h4 v1 h-4Z M49 16 h4 v1 h-4Z M0 17 h4 v1 h-4Z M49 17 h4 v1 h-4Z M0 18 h4 v1 h-4Z M49 18 h4 v1 h-4Z M0 19 h4 v1 h-4Z M49 19 h4 v1 h-4Z M0 20 h4 v1 h-4Z M49 20 h4 v1 h-4Z M0 21 h4 v1 h-4Z M49 21 h4 v1 h-4Z M0 22 h4 v1 h-4Z M49 22 h4 v1 h-4Z M0 23 h4 v1 h-4Z M49 23 h4 v1 h-4Z M0 24 h4 v1 h-4Z M49 24 h4 v1 h-4Z M0 25 h4 v1 h-4Z M49 25 h4 v1 h-4Z M0 26 h4 v1 h-4Z M49 26 h4 v1 h-4Z M0 27 h4 v1 h-4Z M49 27 h4 v1 h-4Z M0 28 h4 v1 h-4Z M49 28 h4 v1 h-4Z M0 29 h4 v1 h-4Z M49 29 h4 v1 h-4Z M0 30 h4 v1 h-4Z M49 30 h4 v1 h-4Z M0 31 h4 v1 h-4Z M49 31 h4 v1 h-4Z M0 32 h4 v1 h-4Z M49 32 h4 v1 h-4Z M0 33 h4 v1 h-4Z M49 33 h4 v1 h-4Z M0 34 h4 v1 h-4Z M49 34 h4 v1 h-4Z M0 35 h4 v1 h-4Z M49 35 h4 v1 h-4Z M0 36 h4 v1 h-4Z M49 36 h4 v1 h-4Z M0 37 h4 v1 h-4Z M49 37 h4 v1 h-4Z M0 38 h4 v1 h-4Z M49 38 h4 v1 h-4Z M0 39 h4 v1 h-4Z M49 39 h4 v1 h-4Z M0 40 h4 v1 h-4Z M49 40 h4 v1 h-4Z M0 41 h4 v1 h-4Z M49 41 h4 v1 h-4Z M0 42 h4 v1 h-4Z M49 42 h4 v1 h-4Z M0 43 h4 v1 h-4Z M49 43 h4 v1 h-4Z M0 44 h4 v1 h-4Z M49 44 h4 v1 h-4Z M0 45 h4 v1 h-4Z M49 45 h4 v1 h-4Z M0 46 h4 v1 h-4Z M49 46 h4 v1 h-4Z M0 47 h4 v1 h-4Z M49 47 h4 v1 h-4Z M0 48 h4 v1 h-4Z M49 48 h4 v1 h-4Z M0 49 h53 v1 h-53Z M0 50 h53 v1 h-53Z M0 51 h53 v1 h-53Z M0 52 h53 v1 h-53Z " /><path class="qr-512 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 41 h1 v1 h-1Z " /><path class="qr-1024 " stroke="transparent" fill="#000" fill-opacity="1" d="M13 4 h1 v1 h-1Z M15 4 h1 v1 h-1Z M17 4 h1 v1 h-1Z M19 4 h1 v1 h-1Z M21 4 h1 v1 h-1Z M24 4 h1 v1 h-1Z M26 4 h1 v1 h-1Z M31 4 h4 v1 h-4Z M37 4 h1 v1 h-1Z M13 5 h4 v1 h-4Z M22 5 h1 v1 h-1Z M24 5 h3 v1 h-3Z M28 5 h4 v1 h-4Z M34 5 h1 v1 h-1Z M36 5 h2 v1 h-2Z M14 6 h1 v1 h-1Z M18 6 h1 v1 h-1Z M20 6 h2 v1 h-2Z M24 6 h1 v1 h-1Z M26 6 h3 v1 h-3Z M30 6 h1 v1 h-1Z M32 6 h3 v1 h-3Z M36 6 h2 v1 h-2Z M14 7 h1 v1 h-1Z M16 7 h1 v1 h-1Z M18 7 h1 v1 h-1Z M20 7 h1 v1 h-1Z M23 7 h3 v1 h-3Z M29 7 h2 v1 h-2Z M32 7 h1 v1 h-1Z M36 7 h1 v1 h-1Z M16 8 h1 v1 h-1Z M18 8 h5 v1 h-5Z M29 8 h1 v1 h-1Z M32 8 h3 v1 h-3Z M13 9 h1 v1 h-1Z M17 9 h2 v1 h-2Z M20 9 h2 v1 h-2Z M31 9 h1 v1 h-1Z M33 9 h2 v1 h-2Z M36 9 h2 v1 h-2Z M14 11 h1 v1 h-1Z M17 11 h3 v1 h-3Z M21 11 h2 v1 h-2Z M29 11 h1 v1 h-1Z M31 11 h1 v1 h-1Z M33 11 h1 v1 h-1Z M38 11 h1 v1 h-1Z M40 11 h1 v1 h-1Z M14 12 h2 v1 h-2Z M17 12 h2 v1 h-2Z M20 12 h1 v1 h-1Z M29 12 h2 v1 h-2Z M33 12 h2 v1 h-2Z M36 12 h2 v1 h-2Z M39 12 h2 v1 h-2Z M5 13 h1 v1 h-1Z M8 13 h2 v1 h-2Z M14 13 h1 v1 h-1Z M17 13 h6 v1 h-6Z M24 13 h2 v1 h-2Z M28 13 h2 v1 h-2Z M31 13 h3 v1 h-3Z M37 13 h1 v1 h-1Z M39 13 h1 v1 h-1Z M41 13 h1 v1 h-1Z M46 13 h1 v1 h-1Z M8 14 h1 v1 h-1Z M11 14 h1 v1 h-1Z M14 14 h1 v1 h-1Z M18 14 h1 v1 h-1Z M22 14 h1 v1 h-1Z M26 14 h2 v1 h-2Z M31 14 h1 v1 h-1Z M33 14 h2 v1 h-2Z M36 14 h1 v1 h-1Z M39 14 h4 v1 h-4Z M44 14 h1 v1 h-1Z M48 14 h1 v1 h-1Z M4 15 h1 v1 h-1Z M6 15 h3 v1 h-3Z M11 15 h3 v1 h-3Z M16 15 h1 v1 h-1Z M19 15 h1 v1 h-1Z M22 15 h2 v1 h-2Z M28 15 h2 v1 h-2Z M31 15 h2 v1 h-2Z M34 15 h2 v1 h-2Z M38 15 h2 v1 h-2Z M41 15 h1 v1 h-1Z M43 15 h1 v1 h-1Z M46 15 h1 v1 h-1Z M6 16 h1 v1 h-1Z M8 16 h2 v1 h-2Z M11 16 h2 v1 h-2Z M14 16 h6 v1 h-6Z M21 16 h1 v1 h-1Z M24 16 h1 v1 h-1Z M27 16 h2 v1 h-2Z M30 16 h3 v1 h-3Z M35 16 h1 v1 h-1Z M37 16 h1 v1 h-1Z M40 16 h1 v1 h-1Z M42 16 h2 v1 h-2Z M46 16 h1 v1 h-1Z M48 16 h1 v1 h-1Z M5 17 h4 v1 h-4Z M11 17 h1 v1 h-1Z M15 17 h1 v1 h-1Z M17 17 h1 v1 h-1Z M20 17 h4 v1 h-4Z M26 17 h3 v1 h-3Z M31 17 h1 v1 h-1Z M34 17 h3 v1 h-3Z M40 17 h1 v1 h-1Z M43 17 h4 v1 h-4Z M48 17 h1 v1 h-1Z M4 18 h2 v1 h-2Z M7 18 h2 v1 h-2Z M11 18 h1 v1 h-1Z M13 18 h1 v1 h-1Z M15 18 h1 v1 h-1Z M17 18 h1 v1 h-1Z M20 18 h1 v1 h-1Z M23 18 h1 v1 h-1Z M26 18 h1 v1 h-1Z M30 18 h1 v1 h-1Z M34 18 h2 v1 h-2Z M41 18 h1 v1 h-1Z M43 18 h1 v1 h-1Z M46 18 h3 v1 h-3Z M4 19 h1 v1 h-1Z M7 19 h3 v1 h-3Z M12 19 h1 v1 h-1Z M14 19 h2 v1 h-2Z M21 19 h2 v1 h-2Z M29 19 h1 v1 h-1Z M31 19 h3 v1 h-3Z M36 19 h2 v1 h-2Z M40 19 h1 v1 h-1Z M43 19 h1 v1 h-1Z M48 19 h1 v1 h-1Z M4 20 h1 v1 h-1Z M6 20 h4 v1 h-4Z M12 20 h1 v1 h-1Z M14 20 h1 v1 h-1Z M18 20 h2 v1 h-2Z M21 20 h1 v1 h-1Z M23 20 h1 v1 h-1Z M26 20 h2 v1 h-2Z M32 20 h7 v1 h-7Z M41 20 h2 v1 h-2Z M44 20 h2 v1 h-2Z M48 20 h1 v1 h-1Z M4 21 h2 v1 h-2Z M8 21 h2 v1 h-2Z M15 21 h1 v1 h-1Z M17 21 h3 v1 h-3Z M21 21 h1 v1 h-1Z M24 21 h1 v1 h-1Z M26 21 h1 v1 h-1Z M28 21 h1 v1 h-1Z M32 21 h2 v1 h-2Z M35 21 h1 v1 h-1Z M37 21 h1 v1 h-1Z M41 21 h1 v1 h-1Z M44 21 h2 v1 h-2Z M48 21 h1 v1 h-1Z M4 22 h1 v1 h-1Z M6 22 h2 v1 h-2Z M11 22 h1 v1 h-1Z M14 22 h1 v1 h-1Z M16 22 h2 v1 h-2Z M19 22 h2 v1 h-2Z M25 22 h2 v1 h-2Z M28 22 h1 v1 h-1Z M30 22 h5 v1 h-5Z M37 22 h3 v1 h-3Z M43 22 h1 v1 h-1Z M46 22 h3 v1 h-3Z M4 23 h5 v1 h-5Z M11 23 h5 v1 h-5Z M17 23 h1 v1 h-1Z M20 23 h1 v1 h-1Z M22 23 h1 v1 h-1Z M25 23 h2 v1 h-2Z M29 23 h3 v1 h-3Z M34 23 h3 v1 h-3Z M38 23 h2 v1 h-2Z M42 23 h3 v1 h-3Z M4 24 h3 v1 h-3Z M13 24 h2 v1 h-2Z M16 24 h2 v1 h-2Z M23 24 h1 v1 h-1Z M29 24 h1 v1 h-1Z M31 24 h2 v1 h-2Z M36 24 h1 v1 h-1Z M4 25 h1 v1 h-1Z M6 25 h1 v1 h-1Z M13 25 h4 v1 h-4Z M18 25 h1 v1 h-1Z M21 25 h2 v1 h-2Z M32 25 h1 v1 h-1Z M34 25 h3 v1 h-3Z M38 25 h1 v1 h-1Z M47 25 h2 v1 h-2Z M5 26 h2 v1 h-2Z M13 26 h1 v1 h-1Z M15 26 h8 v1 h-8Z M29 26 h1 v1 h-1Z M31 26 h2 v1 h-2Z M34 26 h1 v1 h-1Z M36 26 h1 v1 h-1Z M38 26 h1 v1 h-1Z M46 26 h3 v1 h-3Z M4 27 h2 v1 h-2Z M7 27 h1 v1 h-1Z M14 27 h2 v1 h-2Z M17 27 h3 v1 h-3Z M30 27 h3 v1 h-3Z M34 27 h1 v1 h-1Z M37 27 h1 v1 h-1Z M39 27 h1 v1 h-1Z M18 28 h2 v1 h-2Z M22 28 h2 v1 h-2Z M29 28 h1 v1 h-1Z M32 28 h3 v1 h-3Z M36 28 h3 v1 h-3Z M47 28 h1 v1 h-1Z M5 29 h1 v1 h-1Z M8 29 h1 v1 h-1Z M11 29 h3 v1 h-3Z M16 29 h1 v1 h-1Z M19 29 h5 v1 h-5Z M30 29 h1 v1 h-1Z M37 29 h1 v1 h-1Z M41 29 h2 v1 h-2Z M46 29 h1 v1 h-1Z M4 30 h3 v1 h-3Z M9 30 h1 v1 h-1Z M12 30 h1 v1 h-1Z M14 30 h1 v1 h-1Z M16 30 h3 v1 h-3Z M21 30 h2 v1 h-2Z M26 30 h1 v1 h-1Z M29 30 h1 v1 h-1Z M33 30 h2 v1 h-2Z M36 30 h4 v1 h-4Z M41 30 h1 v1 h-1Z M43 30 h2 v1 h-2Z M48 30 h1 v1 h-1Z M5 31 h2 v1 h-2Z M8 31 h1 v1 h-1Z M11 31 h2 v1 h-2Z M14 31 h3 v1 h-3Z M18 31 h1 v1 h-1Z M20 31 h3 v1 h-3Z M24 31 h2 v1 h-2Z M27 31 h1 v1 h-1Z M32 31 h1 v1 h-1Z M34 31 h2 v1 h-2Z M38 31 h2 v1 h-2Z M41 31 h1 v1 h-1Z M46 31 h1 v1 h-1Z M4 32 h1 v1 h-1Z M6 32 h2 v1 h-2Z M11 32 h2 v1 h-2Z M14 32 h2 v1 h-2Z M17 32 h1 v1 h-1Z M19 32 h2 v1 h-2Z M22 32 h1 v1 h-1Z M25 32 h1 v1 h-1Z M30 32 h3 v1 h-3Z M35 32 h1 v1 h-1Z M37 32 h1 v1 h-1Z M42 32 h2 v1 h-2Z M46 32 h1 v1 h-1Z M48 32 h1 v1 h-1Z M6 33 h1 v1 h-1Z M8 33 h1 v1 h-1Z M11 33 h2 v1 h-2Z M15 33 h1 v1 h-1Z M18 33 h1 v1 h-1Z M20 33 h1 v1 h-1Z M22 33 h1 v1 h-1Z M25 33 h1 v1 h-1Z M27 33 h1 v1 h-1Z M29 33 h1 v1 h-1Z M32 33 h1 v1 h-1Z M34 33 h3 v1 h-3Z M39 33 h1 v1 h-1Z M45 33 h1 v1 h-1Z M47 33 h1 v1 h-1Z M4 34 h1 v1 h-1Z M11 34 h1 v1 h-1Z M13 34 h6 v1 h-6Z M21 34 h2 v1 h-2Z M24 34 h1 v1 h-1Z M26 34 h2 v1 h-2Z M29 34 h2 v1 h-2Z M32 34 h1 v1 h-1Z M34 34 h2 v1 h-2Z M40 34 h1 v1 h-1Z M42 34 h1 v1 h-1Z M44 34 h4 v1 h-4Z M5 35 h1 v1 h-1Z M7 35 h1 v1 h-1Z M11 35 h2 v1 h-2Z M15 35 h1 v1 h-1Z M21 35 h2 v1 h-2Z M28 35 h2 v1 h-2Z M31 35 h1 v1 h-1Z M38 35 h3 v1 h-3Z M45 35 h1 v1 h-1Z M47 35 h2 v1 h-2Z M4 36 h1 v1 h-1Z M7 36 h1 v1 h-1Z M11 36 h1 v1 h-1Z M13 36 h2 v1 h-2Z M16 36 h4 v1 h-4Z M21 36 h1 v1 h-1Z M25 36 h2 v1 h-2Z M29 36 h3 v1 h-3Z M34 36 h1 v1 h-1Z M36 36 h6 v1 h-6Z M44 36 h4 v1 h-4Z M4 37 h1 v1 h-1Z M7 37 h3 v1 h-3Z M12 37 h1 v1 h-1Z M15 37 h2 v1 h-2Z M21 37 h3 v1 h-3Z M25 37 h1 v1 h-1Z M28 37 h2 v1 h-2Z M31 37 h2 v1 h-2Z M34 37 h1 v1 h-1Z M37 37 h1 v1 h-1Z M40 37 h3 v1 h-3Z M44 37 h1 v1 h-1Z M48 37 h1 v1 h-1Z M20 38 h3 v1 h-3Z M26 38 h1 v1 h-1Z M31 38 h2 v1 h-2Z M36 38 h1 v1 h-1Z M39 38 h1 v1 h-1Z M41 38 h1 v1 h-1Z M46 38 h3 v1 h-3Z M12 39 h1 v1 h-1Z M16 39 h2 v1 h-2Z M23 39 h1 v1 h-1Z M27 39 h3 v1 h-3Z M31 39 h6 v1 h-6Z M38 39 h2 v1 h-2Z M41 39 h1 v1 h-1Z M44 39 h1 v1 h-1Z M48 39 h1 v1 h-1Z M11 40 h1 v1 h-1Z M16 40 h2 v1 h-2Z M19 40 h1 v1 h-1Z M23 40 h1 v1 h-1Z M29 40 h3 v1 h-3Z M35 40 h2 v1 h-2Z M45 40 h1 v1 h-1Z M48 40 h1 v1 h-1Z M18 41 h6 v1 h-6Z M29 41 h3 v1 h-3Z M33 41 h1 v1 h-1Z M36 41 h1 v1 h-1Z M38 41 h1 v1 h-1Z M47 41 h2 v1 h-2Z M14 42 h1 v1 h-1Z M17 42 h3 v1 h-3Z M22 42 h2 v1 h-2Z M35 42 h1 v1 h-1Z M38 42 h1 v1 h-1Z M45 42 h4 v1 h-4Z M13 43 h5 v1 h-5Z M23 43 h1 v1 h-1Z M29 43 h1 v1 h-1Z M31 43 h2 v1 h-2Z M34 43 h1 v1 h-1Z M36 43 h2 v1 h-2Z M39 43 h1 v1 h-1Z M47 43 h1 v1 h-1Z M15 44 h1 v1 h-1Z M17 44 h1 v1 h-1Z M19 44 h1 v1 h-1Z M23 44 h1 v1 h-1Z M31 44 h1 v1 h-1Z M35 44 h4 v1 h-4Z M47 44 h2 v1 h-2Z M16 45 h1 v1 h-1Z M18 45 h1 v1 h-1Z M21 45 h1 v1 h-1Z M24 45 h2 v1 h-2Z M31 45 h1 v1 h-1Z M33 45 h5 v1 h-5Z M39 45 h3 v1 h-3Z M15 46 h3 v1 h-3Z M19 46 h1 v1 h-1Z M21 46 h1 v1 h-1Z M23 46 h2 v1 h-2Z M26 46 h1 v1 h-1Z M28 46 h1 v1 h-1Z M31 46 h11 v1 h-11Z M44 46 h3 v1 h-3Z M48 46 h1 v1 h-1Z M14 47 h1 v1 h-1Z M16 47 h2 v1 h-2Z M19 47 h1 v1 h-1Z M21 47 h1 v1 h-1Z M26 47 h3 v1 h-3Z M32 47 h1 v1 h-1Z M35 47 h1 v1 h-1Z M38 47 h4 v1 h-4Z M45 47 h1 v1 h-1Z M47 47 h1 v1 h-1Z M18 48 h1 v1 h-1Z M21 48 h1 v1 h-1Z M23 48 h2 v1 h-2Z M28 48 h2 v1 h-2Z M35 48 h1 v1 h-1Z M39 48 h1 v1 h-1Z M41 48 h1 v1 h-1Z M44 48 h1 v1 h-1Z M47 48 h2 v1 h-2Z " /><path class="qr-1536 " stroke="transparent" fill="#000" fill-opacity="1" d="M4 4 h7 v1 h-7Z M42 4 h7 v1 h-7Z M4 5 h1 v1 h-1Z M10 5 h1 v1 h-1Z M42 5 h1 v1 h-1Z M48 5 h1 v1 h-1Z M4 6 h1 v1 h-1Z M10 6 h1 v1 h-1Z M42 6 h1 v1 h-1Z M48 6 h1 v1 h-1Z M4 7 h1 v1 h-1Z M10 7 h1 v1 h-1Z M42 7 h1 v1 h-1Z M48 7 h1 v1 h-1Z M4 8 h1 v1 h-1Z M10 8 h1 v1 h-1Z M42 8 h1 v1 h-1Z M48 8 h1 v1 h-1Z M4 9 h1 v1 h-1Z M10 9 h1 v1 h-1Z M42 9 h1 v1 h-1Z M48 9 h1 v1 h-1Z M4 10 h7 v1 h-7Z M42 10 h7 v1 h-7Z M4 42 h7 v1 h-7Z M4 43 h1 v1 h-1Z M10 43 h1 v1 h-1Z M4 44 h1 v1 h-1Z M10 44 h1 v1 h-1Z M4 45 h1 v1 h-1Z M10 45 h1 v1 h-1Z M4 46 h1 v1 h-1Z M10 46 h1 v1 h-1Z M4 47 h1 v1 h-1Z M10 47 h1 v1 h-1Z M4 48 h7 v1 h-7Z " /><path class="qr-2560 " stroke="transparent" fill="#000" fill-opacity="1" d="M24 8 h5 v1 h-5Z M24 9 h1 v1 h-1Z M28 9 h1 v1 h-1Z M24 10 h1 v1 h-1Z M26 10 h1 v1 h-1Z M28 10 h1 v1 h-1Z M24 11 h1 v1 h-1Z M28 11 h1 v1 h-1Z M24 12 h5 v1 h-5Z M8 24 h5 v1 h-5Z M24 24 h5 v1 h-5Z M40 24 h5 v1 h-5Z M8 25 h1 v1 h-1Z M12 25 h1 v1 h-1Z M24 25 h1 v1 h-1Z M28 25 h1 v1 h-1Z M40 25 h1 v1 h-1Z M44 25 h1 v1 h-1Z M8 26 h1 v1 h-1Z M10 26 h1 v1 h-1Z M12 26 h1 v1 h-1Z M24 26 h1 v1 h-1Z M26 26 h1 v1 h-1Z M28 26 h1 v1 h-1Z M40 26 h1 v1 h-1Z M42 26 h1 v1 h-1Z M44 26 h1 v1 h-1Z M8 27 h1 v1 h-1Z M12 27 h1 v1 h-1Z M24 27 h1 v1 h-1Z M28 27 h1 v1 h-1Z M40 27 h1 v1 h-1Z M44 27 h1 v1 h-1Z M8 28 h5 v1 h-5Z M24 28 h5 v1 h-5Z M40 28 h5 v1 h-5Z M24 40 h5 v1 h-5Z M40 40 h5 v1 h-5Z M24 41 h1 v1 h-1Z M28 41 h1 v1 h-1Z M40 41 h1 v1 h-1Z M44 41 h1 v1 h-1Z M24 42 h1 v1 h-1Z M26 42 h1 v1 h-1Z M28 42 h1 v1 h-1Z M40 42 h1 v1 h-1Z M42 42 h1 v1 h-1Z M44 42 h1 v1 h-1Z M24 43 h1 v1 h-1Z M28 43 h1 v1 h-1Z M40 43 h1 v1 h-1Z M44 43 h1 v1 h-1Z M24 44 h5 v1 h-5Z M40 44 h5 v1 h-5Z " /><path class="qr-3072 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 10 h1 v1 h-1Z M14 10 h1 v1 h-1Z M16 10 h1 v1 h-1Z M18 10 h1 v1 h-1Z M20 10 h1 v1 h-1Z M22 10 h1 v1 h-1Z M30 10 h1 v1 h-1Z M32 10 h1 v1 h-1Z M34 10 h1 v1 h-1Z M36 10 h1 v1 h-1Z M38 10 h1 v1 h-1Z M40 10 h1 v1 h-1Z M10 12 h1 v1 h-1Z M10 14 h1 v1 h-1Z M10 16 h1 v1 h-1Z M10 18 h1 v1 h-1Z M10 20 h1 v1 h-1Z M10 22 h1 v1 h-1Z M10 30 h1 v1 h-1Z M10 32 h1 v1 h-1Z M10 34 h1 v1 h-1Z M10 36 h1 v1 h-1Z M10 38 h1 v1 h-1Z M10 40 h1 v1 h-1Z " /><path class="qr-3584 " stroke="transparent" fill="#000" fill-opacity="1" d="M12 4 h1 v1 h-1Z M12 7 h1 v1 h-1Z M6 12 h1 v1 h-1Z M8 12 h2 v1 h-2Z M12 12 h1 v1 h-1Z M41 12 h1 v1 h-1Z M45 12 h1 v1 h-1Z M48 12 h1 v1 h-1Z M12 43 h1 v1 h-1Z M12 44 h1 v1 h-1Z M12 46 h1 v1 h-1Z " /><path class="qr-4096 " stroke="transparent" fill="#000" fill-opacity="1" d="M40 4 h1 v1 h-1Z M39 5 h1 v1 h-1Z M39 6 h1 v1 h-1Z M39 7 h2 v1 h-2Z M38 8 h3 v1 h-3Z M8 38 h1 v1 h-1Z M5 39 h4 v1 h-4Z M4 40 h1 v1 h-1Z M7 40 h2 v1 h-2Z " /><path class="qr-5632 " stroke="transparent" fill="#000" fill-opacity="1" d="M6 6 h3 v1 h-3Z M44 6 h3 v1 h-3Z M6 7 h3 v1 h-3Z M44 7 h3 v1 h-3Z M6 8 h3 v1 h-3Z M44 8 h3 v1 h-3Z M6 44 h3 v1 h-3Z M6 45 h3 v1 h-3Z M6 46 h3 v1 h-3Z " /></svg>

    </a>
    <figcaption aria-hidden="true" class="hidden" hidden>Un soutien tipeee pour Stéphane HUC</figcaption>
</figure>


<h2 id="qui">Qui</h2>
<h3 id="2020">2020</h3>
<p>⇒ Au mois d&rsquo;Octobre :</p>
<ul>
<li>@scorpus</li>
</ul>
<h3 id="2022">2022</h3>
<p>⇒ Au mois de Novembre :</p>
<ul>
<li>un certain @Cascador</li>
</ul>
<h2 id="quoi">Quoi</h2>
<h3 id="2020-1">2020</h3>
<ul>
<li>L&rsquo;équivalent d&rsquo;une <strong>trappiste rochefort 10</strong> : 5 €</li>
</ul>
<h3 id="2022-1">2022</h3>
<ul>
<li>5 dizaines de roros</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Informations à-propos des dons]]></summary>
        <published>2020-02-21T19:59:41+01:00</published>
        <updated>2024-02-12T12:45:22+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:550a5455-57ff-68dc-c071-49957089f060</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openwrt/about/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenWRT : Présentation du projet</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenWRT" scheme="http://doc.huc.fr.eu.org/fr/tags/openwrt/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenWRT</strong> est un système d&rsquo;exploitation GNU/Linux ciblant les périphériques
embarqués <em>(typiquement des routeurs sans fils)</em>.</p>
<p>Ce n&rsquo;est pas un projet monolitique , bien au contraire, c&rsquo;est plus un framework
fournissant les outils logiciels nécessaires afin de fournir un système de fichiers
complet, de permettre la création de micrologiciels <em>(en anglais : firmware)</em>
selon le matériel et tout autour une distribution complète qui permet à
l&rsquo;administrateur/utilisateur de la configurer &ldquo;aux petits oignons&rdquo; permettant
différents usages utiles.</p>
<hr>
<ul>
<li>
<p>OpenWRT : <strong>v19.07.x</strong></p>
</li>
<li>
<p>Le shell est le <strong>ash</strong> du projet <strong><a href="https://www.busybox.net/BusyBox.html" rel="external">Busybox</a></strong>.</p>
</li>
<li>
<p>L&rsquo;éditeur par défaut est <code>vi</code> - <em>si vous n&rsquo;aimez pas, il est possible d&rsquo;en
<a href="/fr/sys/openwrt/about/#gestionnaire-de-paquets">installer</a> d&rsquo;autres, tel <code>nano</code>.</em></p>
</li>
<li>
<p>Les fichiers de configuration se trouvent généralement dans <code>/etc/config/</code> et
portent le nom du service à configurer.</p>
</li>
<li>
<p>Les services sont fonctionnels à partir du répertoire <code>/etc/init.d/</code> et portent
le nom du service ; ils ont pour options les classiques :</p>
<ul>
<li><code>disable</code> : désactiver un service - il ne redémarrera pas lors d&rsquo;un
(re)démarrage du routeur,</li>
<li><code>enable</code> : activer un service - permet le démarrage du service lors du
(re)démarrage du routeur,</li>
<li><code>reload</code> : recharge la configuration du service,</li>
<li><code>restart</code> : redémarre le service,</li>
<li><code>start</code> : démarre le service,</li>
<li><code>stop</code> : arrête le service.</li>
</ul>
</li>
</ul>
<h2 id="installation">Installation</h2>
<h3 id="gestionnaire-de-paquets">Gestionnaire de paquets</h3>
<p>Le gestionnaire de paquets est <code>opkg</code> est intégré de base dans le système ;
hormis la 
<a class="inside" href="/fr/sys/openwrt/opkg-upgrade/" title="Lien interne vers l&#39;article : 'OpenWRT : opkg upgrade (astuce)'">mise-à-jour &#39;one-shot&#39; de plusieurs paquets</a>
,
il a pour propos les différentes possibilités de gestion des paquets, à savoir
installation, configuration, suppression de paquets… <br>
pour en savoir plus : <code>$ opkg ?</code></p>
<p>Si vous avez <a href="/fr/sys/openwrt/about/#install-luci">installé l&rsquo;interface d&rsquo;administration <strong>LuCI</strong></a>,
il est possible de gérer les paquets par le biais du menu &lsquo;System&rsquo; &gt; &lsquo;Software&rsquo;.</p>
<h3 id="install-luci">Install: LuCI</h3>
<p><strong>LuCI</strong> est l&rsquo;interface web d&rsquo;administration. Par défaut, elle n&rsquo;est fonctionnelle
que sur le protocole 






























<span lang="en">HTTP <em>(HyperText Transfer Protocol)</em></span>
















































































.</p>
<p>Installez le paquet avec le gestionnaire de paquets.</p>
<p><code># opkg install luci</code></p>
<p>L&rsquo;installation de <strong>LuCI</strong> installe plusieurs paquets, dont un serveur web
minimaliste nommé <strong><a href="/fr/sys/openwrt/about/#uhttpd">uhttpd</a></strong>, le thème basé sur <strong><a href="https://getbootstrap.com/" rel="external">Bootstrap</a></strong>,
et les dépendances nécessaires pour la gestion de l&rsquo;administration (gestion des
différents protocoles réseaux, du parefeu, etc.).</p>
<p>Pour installer la version supportant 































<span lang="en">HTTPS <em>(HyperText Transfer Protocol Secure)</em></span>















































































 -
<em>ce qui est préférable</em> -, ce sera :</p>
<p><code># opkg install luci-ssl</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : vous devez impérativement avoir une ROM Flash ≥ 8 Mo !</div>

<h4 id="install-langue-fr">Install: Langue FR</h4>
<p>Il est possible d&rsquo;installer la langue française au besoin.</p>
<p>Retrouvez les différents paquets linguistiques :</p>
<ul>
<li>en mode console : <code># opkg list | grep -E &quot;luci-i18n-(.*)-fr&quot;</code></li>
<li>à-travers l&rsquo;interface d&rsquo;administration : menu &lsquo;System&rsquo; &gt; &lsquo;Software&rsquo; puis dans
le champ &lsquo;Filter&rsquo;, écrivez &ldquo;luci-i18n-&rdquo;.</li>
</ul>
<p>N&rsquo;installez pas tous les paquets disponibles, mais seuls ceux qui vous sont vraiment
nécessaires, tels <em>- peut-être -</em> :</p>
<ul>
<li><code>luci-i18n-base-fr</code> pour l&rsquo;interface de base de LuCI.</li>
<li><code>luci-i18n-firewall-fr</code> pour la partie parefeu</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="root">root</h3>
<p>La première ET la plus importante des premières modifications à faire est de changer
le mot de passe de l&rsquo;admin.</p>
<ul>
<li>en mode console, grâce à la commande <code>passwd</code></li>
<li>par l&rsquo;interface d&rsquo;administration <strong>LuCI</strong> - <em>si elle est installée</em> - :
menu &lsquo;System&rsquo; &gt; &lsquo;Administration&rsquo;, onglet &lsquo;Router Password&rsquo; - <em>onglet par défaut</em>.</li>
</ul>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openwrt/System-Administration-SSH-Router-Password-min.png" title="OpenWRT :: Administration Système : Mot de Pass Root">
    <picture>
        
        <source srcset="/images/openwrt/System-Administration-SSH-Router-Password-min_hu_ecae989021bc8ca.webp" type="image/webp">
        
        <img alt="OpenWRT :: Administration Système : Mot de Pass Root" height="76" loading="lazy" src="/images/openwrt/System-Administration-SSH-Router-Password-min_hu_287fa69ea70bd52d.png" type="image/png" width="256">
    </picture>
    </a>
    <figcaption>OpenWRT :: Administration Système : Mot de Pass Root</figcaption>
</figure>
</div>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est fortement recommandé d&rsquo;éviter la connexion <a href="/fr/sys/openwrt/about/#ssh">SSH</a> pour root, prenez
le temps de
<a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">configurer un nouvel utilisateur</a></p>
<p>et de lui donner les droits pour assumer correctement l&rsquo;administration.</p>
</div>

<h3 id="réseaux">Réseaux</h3>
<ul>
<li>La configuration des ports se fait, soit depuis :
<ul>
<li>le fichier <code>/etc/config/network</code>,</li>
<li>l&rsquo;interface d&rsquo;administration <strong>LuCI</strong>, menu &lsquo;Network&rsquo; &gt; &lsquo;Interfaces&rsquo;.</li>
</ul>
</li>
</ul>
<p>Par défaut sont configurées les interfaces :</p>
<ul>
<li><strong>LAN</strong> en mode bridge,</li>
<li><strong>WAN</strong> et <strong>WAN6</strong></li>
</ul>
<p>De plus, il est configuré deux 










































































































<span lang="en">VLAN <em>(Virtual Local Area Network)</em></span>




, à partir du menu &lsquo;Network&rsquo; &gt;
&lsquo;Switch&rsquo;, pour séparer logiciellement le 















































<span lang="en">LAN <em>(Local Area Network)</em></span>































































 du 













































































































<span lang="en">WAN <em>(World Area Network)</em></span>

.</p>
<ul>
<li>Le service est accessible via : <code>/etc/init.d/network</code>.</li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il peut être intéressant de
<a class="inside" href="/fr/sys/openwrt/switch-lan-wan/" title="Lien interne vers l&#39;article : 'OpenWRT: Switch LAN WAN (astuce)'">basculer LAN sur le port 0 et WAN sur le port 4</a>
.</div>

<h3 id="parefeu">Parefeu</h3>
<ul>
<li>La configuration du parefeu se fait, soit depuis :
<ul>
<li>le fichier <code>/etc/config/firewall</code>,</li>
<li>l&rsquo;interface d&rsquo;administration <strong>LuCI</strong>, menu &lsquo;Network&rsquo; &gt; &lsquo;Firewall&rsquo;.</li>
</ul>
</li>
</ul>
<p>Il est possible d&rsquo;écrire directement des règles <strong>iptables</strong> à partir de l&rsquo;onglet
&lsquo;Custom Rules&rsquo;. <br>
Son fichier se trouve être  <code>/etc/firewall.user</code>. C&rsquo;est seulement dans celui-ci
où peut s&rsquo;écrire directement des règles <strong>iptables</strong> ou <strong>ip6tables</strong>.</p>
<ul>
<li>Le service est accessible via : <code>/etc/init.d/firewall</code>.</li>
</ul>
<h3 id="dhcpd">dhcpd</h3>
<p>Le serveur 












<span lang="en">DHCP <em>(Dynamic Host Control Protocol)</em></span>


































































































 est <strong>dnsmasq</strong>, un serveur léger qui fait aussi
office de résolveur 















<span lang="en">DNS <em>(Domain Name Service)</em></span>































































































 Relais <em>(en anglais : DNS Forwarder)</em> et
fait partie du système de base. La pile IPv6 est assurée par le serveur <strong>odhcpd</strong>.</p>
<ul>
<li>La configuration du serveur <strong>dnsmasq</strong> peut se faire, soit par:
<ul>
<li>le fichier <code>/etc/config/dhcp</code></li>
<li>l&rsquo;interface d&rsquo;administration <strong>LuCI</strong>, menu &lsquo;Network&rsquo; &gt; &lsquo;DHCP and DNS&rsquo;.</li>
</ul>
</li>
<li>Les services <code>dnsmasq</code> et <code>odhcpd</code> sont accessibles à partir du même répertoire
d&rsquo;initialisation <code>/etc/init.d</code>.</li>
<li>Les fichiers d&rsquo;enregistrement des baux DHCP sont, pour :
<ul>
<li><strong>dnsmasq</strong> : <code>/tmp/dhcp.leases</code></li>
<li><strong>odhcpd</strong> : <code>/tmp/hosts/odhcpd</code></li>
</ul>
</li>
</ul>
<p>On ne peut fixer/enregistrer des baux DHCP au-travers de LuCI que pour IPv4.</p>
<h3 id="config-luci">Config: LuCI</h3>
<ul>
<li>Le fichier de configuration de <strong>LuCI</strong> est : <code>/etc/config/luci</code> -
<span class="red">évitez d'y toucher, à moins de savoir réellement ce que vous
faîtes !</span>
</li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il est recommandable de modifier l&rsquo;accès à l&rsquo;interface web, certainement
par le biais d&rsquo;un tunnel
<a class="inside" href="/fr/sys/openwrt/ssh/" title="Lien interne vers l&#39;article : ''">SSH</a>
…</div>

<h3 id="ssh">SSH</h3>
<p>C&rsquo;est le serveur <strong>dropbear</strong> - un serveur SSH, seulement v2, léger - qui fait
office, par défaut dans le système de base.
Il gère très bien les clés à courbes elliptiques, tel ed25519.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>La première chose à faire du côté de votre client est d&rsquo;ajouter dans
votre <a class="inside" href="/fr/sec/ssh/configuration-securisee/#message-authentication-codes" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">configuration sécurisée</a>
,
le support de :</p>
<ul>
<li><code>Ciphers aes256-ctr</code></li>
<li><code>HostKeyAlgorithms ssh-rsa</code></li>
<li><code>MACs hmac-sha2-256</code></li>
</ul>
<p>Retrouvez les <a class="inside" href="/fr/sys/openwrt/ssh-tunnel/#d%c3%a9pannage" title="Lien interne vers l&#39;article : 'OpenWRT : Tunnel SSH pour LuCI'">différents codes d&rsquo;erreurs liés à la fin de cet article sur SSH</a>
.</p>
</div>

<hr>
<ul>
<li>Par le biais de l&rsquo;interface web d&rsquo;administration <strong>LuCI</strong>, choisissez le menu
&lsquo;System &gt; Administration&rsquo;, puis l&rsquo;onglet &ldquo;SSH Access&rdquo;.</li>
</ul>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openwrt/System-Administration-SSH-Access-min.png" title="OpenWRT :: Administration Système : Accès SSH">
    <picture>
        
        <source srcset="/images/openwrt/System-Administration-SSH-Access-min_hu_ce0ba6881e70fd84.webp" type="image/webp">
        
        <img alt="OpenWRT :: Administration Système : Accès SSH" height="166" loading="lazy" src="/images/openwrt/System-Administration-SSH-Access-min_hu_bdf0307b55062d5c.png" type="image/png" width="256">
    </picture>
    </a>
    <figcaption>OpenWRT :: Administration Système : Accès SSH</figcaption>
</figure>
</div>
<p>Puis paramétrez ainsi :</p>
<ul>
<li>Interface : choisissez lan</li>
<li>Port : si vous laissez le port par défaut, pas besoin de le spécifier, sinon
modifiez-le.</li>
</ul>
<p>Par mesure de sécurité : laissez non cochées, les trois autres options que sont
&lsquo;Password Authentication&rsquo;, &lsquo;Allow root logins with password&rsquo; et &lsquo;Gateway Ports&rsquo;.
Ainsi nous ne permettrons pas à l&rsquo;identifiant <strong>root</strong> de se connecter, et à
nul compte de pouvoir se connecter par mot-de-passe.
Cela signifie qu&rsquo;il faut ajouter une clé d&rsquo;authentification SSH.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Le seul moment où &lsquo;Password Authentication&rsquo; et &lsquo;Allow root logins with password&rsquo;
seront autorisées, donc cochées, et le temps de définir un</p>
<p><a class="inside" href="/fr/sys/openwrt/sudo/" title="Lien interne vers l&#39;article : 'OpenWRT : sudo'">nouvel utilisateur</a>
… <br>
<strong>Si ce n&rsquo;est pas déjà fait, c&rsquo;est le moment de le faire !</strong></p>
</div>

<p>Il est aussi possible de créer un nouvel utilisateur SSH, en choisissant pour
interface : &lsquo;unspecified&rsquo;,
qui permettrait de créer ledit utilisateur…</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Appréciez cette
<a class="inside" href="/fr/sys/openwrt/ssh-tunnel/" title="Lien interne vers l&#39;article : 'OpenWRT : Tunnel SSH pour LuCI'">méthode</a>
pour sécuriser
LuCI.</div>

<h3 id="uhttpd">uhttpd</h3>
<p>Bien que léger, voire minimaliste <strong>uhttpd</strong> est LE serveur web, <em>par défaut non
installé sur le firmware initram</em>, qui fait fonctionner l&rsquo;interface web
<strong><a href="/fr/sys/openwrt/about/#install-luci">LuCI</a></strong>.</p>
<ul>
<li>La configuration du serveur se fait via : <code>/etc/config/uhttpd</code></li>
<li>Le service est accessible via <code>/etc/init.d/uhttpd</code></li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Par défaut, le serveur <strong>uhttpd</strong> écoute sur toutes les interfaces, partout !</p>
<p>Pensez à minima, par principe de sécurité, à changer les lignes <code>list listen_http</code>
pour cibler seulement l&rsquo;adresse IP de votre LAN, tel que : <br>
<code>list listen_http 192.168.1.1:80</code> - <em>(bien sûr, si votre adresse IP est celle-là,
sinon changez-la selon vos paramétrages)</em> - <br>
idem, pour le port HTTPS, voire pour l&rsquo;IPv6, si vous gérez !</p>
<hr>
<p>Toujours par principe de sécurité, il est recommandé de le démarrer qu&rsquo;en cas
de besoin de configuration et de l&rsquo;arrêter une fois terminée. C&rsquo;est pourquoi,
vous pouvez faire allégrement :</p>
<ul>
<li><code># /etc/init.d/uhttpd disable</code> ainsi il ne redémarrera pas lors de
(re)démarrage du routeur.</li>
<li><code># /etc/init.d/uhttpd start</code> et <code>stop</code> pour réciproquement le démarrer et
l&rsquo;arrêter au besoin.</li>
</ul>
<p>Avantage : Cela permet de libérer les ressources de puissance machine.</p>
<p>Cela sous-entend bien-sûr une connexion <a href="/fr/sys/openwrt/about/#ssh">SSH</a> active !</p>
</div>

<h3 id="restauration">Restauration</h3>
<p>La restauration d&rsquo;une configuration précédente peut se faire par :</p>
<ul>
<li>l&rsquo;interface d&rsquo;administration, menu &lsquo;System&rsquo; &gt; &lsquo;Backup / Flash Firmware&rsquo; puis
dans la section <strong>Restore</strong> soit vous cliquez sur le bouton :
<ul>
<li>[ Perform reset ] qui aura pour propos de remettre à la configuration
initiale du firmware - <strong>nécessite que celui-ci soit de type &ldquo;squashfs&rdquo;</strong></li>
<li>[ Upload archive… ] pour restaurer une configuration précédemment archivée.</li>
</ul>
</li>
</ul>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openwrt/System-Administration-Flash-Restore-min.png" title="OpenWRT :: Administration Système : Restauration">
    <picture>
        
        <source srcset="/images/openwrt/System-Administration-Flash-Restore-min_hu_15b21f2bdfc6ac81.webp" type="image/webp">
        
        <img alt="OpenWRT :: Administration Système : Restauration" height="52" loading="lazy" src="/images/openwrt/System-Administration-Flash-Restore-min_hu_489f65747e61dba6.png" type="image/png" width="256">
    </picture>
    </a>
    <figcaption>OpenWRT :: Administration Système : Restauration</figcaption>
</figure>
</div>
<h3 id="sauvegarde">Sauvegarde</h3>
<p>La sauvegarde de toutes configurations du routeur peut se faire par :</p>
<ul>
<li>l&rsquo;interface d&rsquo;administration, menu &lsquo;System&rsquo; &gt; &lsquo;Backup / Flash Firmware&rsquo; puis
dans la section <strong>Backup</strong> cliquez sur le bouton [ Generate archive ].</li>
</ul>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openwrt/System-Administration-Flash-Backup-min.png" title="OpenWRT :: Administration Système : Sauvegarde">
    <picture>
        
        <source srcset="/images/openwrt/System-Administration-Flash-Backup-min_hu_5f355f13b8336c8d.webp" type="image/webp">
        
        <img alt="OpenWRT :: Administration Système : Sauvegarde" height="45" loading="lazy" src="/images/openwrt/System-Administration-Flash-Backup-min_hu_70f8400468b45383.png" type="image/png" width="256">
    </picture>
    </a>
    <figcaption>OpenWRT :: Administration Système : Sauvegarde</figcaption>
</figure>
</div>
<h3 id="upgrade">Upgrade</h3>
<p>La mise à jour du firmware peut se faire :</p>
<ul>
<li>en mode console - <strong>ce qui semble préférable</strong> - par le biais de la commande
<code>sysupgrade</code> après avoir téléchargé le firmware adéquat.</li>
<li>par l&rsquo;interface d&rsquo;administration, menu &lsquo;System&rsquo; &gt; &lsquo;Backup / Flash Firmware&rsquo; puis
dans la section <strong>Flash new firmware image</strong> cliquez sur le bouton [ Flash image ].</li>
</ul>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openwrt/System-Administration-Flash-Firmware-min.png" title="OpenWRT :: Administration Système : Mise à jour Firmware">
    <picture>
        
        <source srcset="/images/openwrt/System-Administration-Flash-Firmware-min_hu_93624c47bb312f28.webp" type="image/webp">
        
        <img alt="OpenWRT :: Administration Système : Mise à jour Firmware" height="49" loading="lazy" src="/images/openwrt/System-Administration-Flash-Firmware-min_hu_44d5261862970bef.png" type="image/png" width="256">
    </picture>
    </a>
    <figcaption>OpenWRT :: Administration Système : Mise à jour Firmware</figcaption>
</figure>
</div>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il faut être conscient que lors de la mise à jour du firmware, toute
configuration personnalisée hors système sera purgée.</p>
<p>Mieux vaut suivre ce processus de sauvegarde correcte :</p>
<p><a class="inside" href="/fr/sys/openwrt/sysupgrade/" title="Lien interne vers l&#39;article : 'OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)'">OpenWRT : Gérer correctement le processus de mise à niveau (sysupgrade)</a></p>
</div>

<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le wiki du projet OpenWRT : <a href="https://openwrt.org/" rel="external">https://openwrt.org/</a></li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Présentation du projet OpenWRT]]></summary>
        <published>2020-02-20T21:37:23+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:91eecf8d-610b-dd02-5f48-f36c567cf09c</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-fr-lang/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Configurer la langue Française / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Lang" scheme="http://doc.huc.fr.eu.org/fr/tags/lang/" />
        <content type="html"><![CDATA[<h2 id="avoir-les-applications-en-français">Avoir les applications en français</h2>
<p>À configurer dans votre fichier <code>~/.profile</code>, normalement, seule
<code>LC_MESSAGES</code> est nécessaire :</p>
<p><code>export LC_MESSAGES=&quot;fr&quot;</code></p>
<hr>
<p>On peut au besoin  configurer également les autres variables
d&rsquo;environnement <code>LC_*</code>, tel que:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">export LC_CTYPE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr_FR.UTF-8&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export LC_NUMERIC</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">C</span>
</span></span></code></pre></div><p>Il est possible de l&rsquo;écrire légèrement différemment :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">LC_CTYPE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr_FR.UTF-8&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_MESSAGES</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">LC_ALL</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;fr_FR.UTF-8&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">export LC_CTYPE LC_MESSAGES LC_ALL</span>
</span></span></code></pre></div><h2 id="dictionnaires">Dictionnaires</h2>
<p>Il est possible d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#ajouter" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">ajouter</a>

aussi les dictionnaires <strong>aspell-fr</strong> et <strong>ispell-<em>xyz</em>-french</strong>
<em>(<code>xyz</code> est le numéro de la version en cours…)</em> :</p>
<p>Puis mettre le français par défaut avec :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># /usr/local/bin/ispell-config</span>
</span></span></code></pre></div><hr>
<p>Il est possible d&rsquo;y <a class="inside" href="/fr/sys/openbsd/pkg/#ajouter" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">ajouter</a>

aussi les dictionnaires <code>aspell</code> et <code>ispell</code> !</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour la gestion de la langue française sous OpenBSD]]></summary>
        <published>2020-01-19T22:16:40+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:863cc740-7b37-b91d-6ba8-39e308fa0ea4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-limits/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion des Limit(e)s Systèmes / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Limits" scheme="http://doc.huc.fr.eu.org/fr/tags/limits/" />
        <content type="html"><![CDATA[<h2 id="augmenter-les-limites-autorisées">Augmenter les limites autorisées</h2>
<p>Dans le fichier <code>/etc/login.conf</code> , on peut allouer plus de mémoire :</p>
<p>Notez que la classe <code>default</code> est attribuée à chaque utilisateur qui n&rsquo;a
pas de classe particulière dans <code>/etc/master.passwd</code>.
L&rsquo;utilisateur principal se trouve généralement dans la classe <code>staff</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">default:\</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">:path</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin /usr/local/sbin:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :umask=022:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :datasize-max=infinity:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :datasize-cur=4G:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :maxproc-max=512:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :maxproc-cur=256:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :openfiles-cur=512:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :stacksize-cur=4M:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :localcipher=blowfish,a:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :tc=auth-defaults:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        :tc=auth-ftp-defaults:</span>
</span></span></code></pre></div><p>Ensuite, si votre fichier <code>login.conf</code> est conséquent, vous gagnerez en
performance en créant une base de donnée. Pour créer et mettre à jour la
base de donnée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># cap_mkdb /etc/login.conf</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces de gestion des limites systèmes sous OpenBSD]]></summary>
        <published>2020-01-19T22:11:05+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c535df24-2d3f-e46f-2f6c-e20334ade54a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-group/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion des Group(e)s Systèmes sur OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Group" scheme="http://doc.huc.fr.eu.org/fr/tags/group/" />
        <content type="html"><![CDATA[<h2 id="ajouter-un-utilisateur-au-groupe-wheel">Ajouter un utilisateur au groupe wheel</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usermod -G wheel nom_user</span>
</span></span></code></pre></div><h2 id="autoriser-les-utilisateurs-du-groupe-wheel-à-utiliser-doas">Autoriser les utilisateurs du groupe wheel à utiliser doas</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Ce qui suit n&rsquo;est qu&rsquo;un exemple, parmi tant d&rsquo;autres…</p>
<p>Pour de plus amples informations, lisez absolument la page de manuel de
<a href="http://man.openbsd.org/doas.conf.5" rel="external"><code>doas.conf</code>(5)</a> !</p>
</div>

<p>Dans le fichier <code>/etc/doas.conf</code> :</p>
<p><code>permit setenv { ENV PS1 } :wheel</code></p>
<p><em>Puis logout, login !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces de gestion des groupes systèmes sous OpenBSD]]></summary>
        <published>2020-01-19T22:06:28+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:eb446da1-790a-ebd0-1123-af1fe72c6467</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/kit-survie/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Kit de survie sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="kit" scheme="http://doc.huc.fr.eu.org/fr/tags/kit/" />
        <category term="survie" scheme="http://doc.huc.fr.eu.org/fr/tags/survie/" />
        <content type="html"><![CDATA[<h2 id="kit-de-survie-sous-openbsd">Kit de survie sous OpenBSD</h2>
<p>Vous débutez sur OpenBSD ?</p>
<ol>
<li>assurez-vous d&rsquo;avoir lu la page &ldquo;<a class="inside" href="/fr/sys/openbsd/after-install/" title="Lien interne vers l&#39;article : 'Que faire après l&#39;installation d’OpenBSD ?'">Que faire après l&#39;installation d’OpenBSD ?</a>&rdquo; !</li>
</ol>
<p>Vous avez oublié une commande bien utile après avoir vécu 15 jours chez
belle-maman ?</p>
<p>Cette page recense quelques astuces relatives à la gestion d&rsquo;OpenBSD</p>
<h2 id="gestion-des-paquets">Gestion des paquets</h2>
<p>⇒ En premier, <strong>lisez ces <a class="inside" href="/fr/sys/openbsd/pkg/#explications" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">explications</a>
</strong>
;)</p>
<p>⇒ Le miroir utilisé pour chercher les paquets est indiqué dans le fichier
<a class="inside" href="/fr/sys/openbsd/installurl/" title="Lien interne vers l&#39;article : 'installurl : localisation du serveur miroir OpenBSD'">/etc/installurl</a>
.</p>
<p>Vous trouverez une <a href="https://www.openbsd.org/ftp.htm" rel="external">liste de miroirs</a>
officiels.</p>
<h2 id="gestion-des-services">Gestion des services</h2>
<p>Les services sont gérés avec <a class="inside" href="/fr/sys/openbsd/rcctl/" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">rcctl</a>
 !</p>
<h2 id="mettre-à-jour">Mettre à jour</h2>
<p>⇒ Pour mettre à jour le système, il faut utiliser l&rsquo;outil
<code><a class="inside" href="/fr/sys/openbsd/syspatch/" title="Lien interne vers l&#39;article : 'Syspatch : gérer les correctifs binaires du système de base sous OpenBSD'">syspatch</a>
</code></p>
<p>⇒ Pour <code><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">mettre à jour</a>
</code>
les paquets, utilisez l&rsquo;outil <code>pkg_add</code> avec l&rsquo;option <code>-u</code>.</p>
<h2 id="sudo">sudo?</h2>
<p><code>sudo</code> ? inconnu !</p>
<p>Ici, c&rsquo;est <a href="https://man.openbsd.org/doas" rel="external"><code>doas</code>(1)</a>.</p>
<h2 id="charge-système-">Charge système ?</h2>
<p>Veuillez lire notre page d&rsquo;information à-propos de l&rsquo;outil
<code><a class="inside" href="/fr/sys/openbsd/systat/" title="Lien interne vers l&#39;article : 'Systat : Voir la charge de la machine'">systat</a>
</code>.</p>
<h2 id="ajouter-une-imprimante">Ajouter une imprimante</h2>
<p>Le plus simple est :</p>
<ul>
<li>d&rsquo;installer le serveur <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
</li>
<li>puis d&rsquo;ouvrir un navigateur à l&rsquo;adresse
<code>http://localhost:631</code> et aller dans la partie administration en tant
qu&rsquo;administrateur système.</li>
</ul>
<h2 id="autres-astuces">Autres Astuces</h2>
<p>Là, c&rsquo;est le must… oui, oui… nous vous avons concocté plusieurs astuces,
toutes recensées sur la page &ldquo;<a class="inside" href="/fr/sys/openbsd/tips/" title="Lien interne vers l&#39;article : 'Trucs et astuces pour OpenBSD'">Trucs et astuces pour OpenBSD</a>&rdquo;.</p>
<p>Alors, profitez-en, régalez-vous - c&rsquo;est fait pour cela  :p</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Que faire pour survivre sur OpenBSD quand on découvre… OpenBSD]]></summary>
        <published>2020-01-19T21:58:22+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:417540a8-2b87-4a5b-85d4-6402ab259af0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-cpu/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Informations CPU / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="CPU" scheme="http://doc.huc.fr.eu.org/fr/tags/cpu/" />
        <content type="html"><![CDATA[<h2 id="détecter-le-nombre-de-processeurs">Détecter le nombre de processeurs</h2>
<p>⇒ La commande ci-dessous détecte le nombre de CPU :</p>
<p><code>$ sysctl hw.ncpu</code></p>
<p>⇒ La commande suivante détecte le nombre de coeurs / CPU :</p>
<p><code>$ sysctl hw.ncpufound</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour obtenir les informations CPU sur OpenBSD]]></summary>
        <published>2020-01-19T21:57:54+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1e7c92fe-dad4-b1ff-fa79-047c80f2e8ae</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-boot/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion du boot / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="boot" scheme="http://doc.huc.fr.eu.org/fr/tags/boot/" />
        <content type="html"><![CDATA[<h2 id="réduire-le-temps-de-démarrage">Réduire le temps de démarrage</h2>
<p>Par défaut, le démarreur attend 5 secondes avant de commencer le
lancement d&rsquo;OpenBSD. Pour réduire ce temps, mettez une ligne comme
celle-ci dans le fichier <code>/etc/boot.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">set timeout 1</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Différentes astuces sur la gestion du boot sous OpenBSD]]></summary>
        <published>2020-01-19T21:54:39+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:132f2d05-4373-1869-e8cb-55715413ad0b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-audio/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion du Son / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="audio" scheme="http://doc.huc.fr.eu.org/fr/tags/audio/" />
        <content type="html"><![CDATA[<h2 id="enregistrement-audio">Enregistrement Audio</h2>
<p>Par défaut, depuis OpenBSD 6.4, pour des raisons de confidentialité,
l&rsquo;enregistrement audio est désactivé !</p>
<p>Pour le réactiver : <code># sysctl kern.audio.record=1</code></p>
<p>N&rsquo;oubliez pas de modifier le fichier <code>/etc/sysctl.conf</code> en conséquence,
si vous désirez qu&rsquo;il soit actif dès le démarrage :<br>
<code># echo kern.audio.record=1 &gt;&gt; /etc/sysctl.conf</code></p>
<p>Pour chaque périphérique mixer, <code>record.enable</code> peut être paramétré sur :</p>
<ul>
<li><code>off</code> (<em>toujours éteint</em>),</li>
<li><code>on</code> (<em>toujours actif</em>),</li>
<li>ou <code>sysctl</code> (<em>par défaut : suit l&rsquo;état du paramètre <code>kern.audio.record</code> de <code>sysctl</code></em>).</li>
</ul>
<h2 id="gérer-le-volume-sonore">Gérer le volume sonore</h2>
<p>Il peut être utile d&rsquo;ajouter votre utilisateur au groupe <code>operator</code> :<br>
<code># usermod -G operator votre-id</code></p>
<h3 id="sndioctl">sndioctl</h3>
<p><strong>À partir d&rsquo;OpenBSD 6.7, c&rsquo;est l&rsquo;outil <a href="https://man.openbsd.org/sndioctl" rel="external">sndioctl(1)</a></strong>
qui est utilisé. Par défaut, il n&rsquo;y a aucune option de configuration à
paramétrer. <em>Normalement, il se manipule sans soucis avec les droits
utilisateurs, sans autre nécessité de gestion de droits particuliers</em>.</p>
<p>L&rsquo;outil <code>sndioctl(1)</code> est le contrôleur pour manipuler le dispositif
audio ; par exemple :</p>
<ul>
<li>Pour augmenter le son d&rsquo;environ 10% : <code>$ sndioctl output.level=+0.1</code></li>
<li>Pour mettre en mode muet : <code>$ sndioctl output.mute=1</code></li>
<li>Pour enlever le mode muet : <code>$ sndioctl output.mute=!</code></li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Vous désirez avoir l&rsquo;affichage sous forme de pourcentage ?</p>
<p>⇒ Utilisez : <br>
<code>$ sndioctl output.level | awk -F = '{printf &quot;%d\n&quot;,$2*100}'</code></p>
</div>

<h4 id="compréhension-affinée">Compréhension affinée</h4>
<p>Les applications audio qui utilisent la bibliothèque <a href="https://man.openbsd.org/sndio.7" rel="external">sndio(7)</a>
n&rsquo;ont plus accès directement aux matériels audio <em>(au-travers de <code>/dev/audio*</code>)</em>.</p>
<p>OpenBSD exécute le serveur de son <a href="https://man.openbsd.org/sndiod.8" rel="external">sndiod(8)</a>
qui découvrira automatiquement quels sont vos dispositifs audio et
requerra les applications audio qui en ont besoin.</p>
<p>Il existe des exceptions :</p>
<ul>
<li>lorsqu&rsquo;un autre serveur de son est fonctionnel</li>
<li>dues à une configuration spécifique du serveur de son <code>sndiod(8)</code></li>
<li>Deux utilisateurs peuvent essayer d&rsquo;obtenir un accès en même temps au
même dispositif audio en partageant le cookie d&rsquo;authentification.</li>
</ul>
<p><em>(cf : la section <strong><a href="https://man.openbsd.org/sndio.7#AUTHENTICATION" rel="external">AUTHENTICATION</a></strong>
du manpage <code>sndio(7)</code>)</em></p>
<h4 id="vérifier-le-fonctionnement-de-sndiod8">Vérifier le fonctionnement de sndiod(8)</h4>
<p>Il est possible de vérifier que le serveur de son <code>sndiod(8)</code> est
fonctionnel en exécutant : <br>
<code>$ pgrep -lf sndiod</code></p>
<p><em>cf : <a href="http://daemonforums.org/showthread.php?t=11402#post68959" rel="external">source</a></em></p>
<h3 id="mixerctl">mixerctl</h3>
<p><strong>Avant OpenBSD 6.7, c’est la commande <code>mixerctl</code></strong> qui était utile. Vous pouvez lancer la commande seule pour voir toutes les sorties existantes.</p>
<ul>
<li>Pour monter le son : <code>mixerctl outputs.master=+10</code></li>
<li>Pour baisser le son : <code>mixerctl outputs.master=-10</code></li>
<li>Pour mettre en mode muet ou l&rsquo;enlever : <code>mixerctl outputs.mute=toggle</code></li>
</ul>
<hr>
<h2 id="paramètres-système">Paramètres système</h2>
<p><strong>Comme le rappelle la <a href="https://www.openbsd.org/faq/faq13.html" rel="external">FAQ Multimédia d&rsquo;OpenBSD</a>,
l&rsquo;outil <code>mixerctl</code> sert toujours à configurer les paramètres</strong> liés au
matériel audio ! <br>
<em>(à utiliser toujours avec des droits administrateurs)</em></p>
<p>Pour savoir ce que gère l&rsquo;outil de votre matériel : <br>
<code># mixerctl -av</code></p>
<p>Quelque soit la modification faite ou à faire, il faut ensuite l&rsquo;écrire
dans le fichier <code>/etc/mixerctl.conf</code> qui n&rsquo;existe pas par défaut :</p>
<p><code># cp /etc/examples/mixerctl.conf /etc/mixerctl.conf</code></p>
<p>Si les modifications ne sont pas écrites dans ce fichier, tout sera
réinitialisé par défaut au redémarrage suivant.</p>
<h3 id="contrôle-des-niveaux-et-mode-muet">Contrôle des niveaux et mode muet</h3>
<p>Lire la FAQ <a href="https://www.openbsd.org/faq/faq13.html#audiolevel" rel="external">Contrôles des niveaux</a>.</p>
<h3 id="économie-dénergie">Économie d&rsquo;énergie</h3>
<p>L&rsquo;<strong>Amplificateur EAPD</strong> est un bouton logiciel utile dans le contexte
des modes d&rsquo;énergie, tels que la veille ou l&rsquo;hibernation. C&rsquo;est une
spécification de la norme Intel HDA - HD Audio.</p>
<p>Lire la FAQ <a href="https://www.openbsd.org/faq/faq13.html#confaudio" rel="external">Amplificateur EAPD</a>
si vous utilisez un ordinateur portable.</p>
<p>Pour information, votre matériel peut très certainement le gérer et déjà
paramétré pour les différentes sorties correspondantes. Vérifiez : <br>
<code># mixerctl -av | grep eapd</code></p>
<h3 id="gestion-de-la-source-denregistrement">Gestion de la source d&rsquo;enregistrement</h3>
<p>Lire la FAQ <a href="https://www.openbsd.org/faq/faq13.html#confaudio" rel="external">Amplificateur EAPD</a></p>
<h3 id="gestion-dun-périphérique-audio-usb">Gestion d&rsquo;un périphérique Audio USB</h3>
<p>Lire la FAQ <a href="https://www.openbsd.org/faq/faq13.html#usbaudio" rel="external">Utiliser une interface USB Audio</a></p>
<h3 id="utiliser-du-matériel-audio-à-distance">Utiliser du matériel audio à distance</h3>
<p>Lire la FAQ <a href="https://www.openbsd.org/faq/faq13.html#audionet" rel="external">Utiliser à distance le matériel audio</a></p>
<h3 id="gestion-dune-sortie-spdif">Gestion d&rsquo;une sortie SPDIF</h3>
<p>Pour gérer le son sur une sortie SPDIF, donc en mode digital, il est
nécessaire de modifier le mode de sortie :</p>
<p><code>outputs.mode=digital</code></p>
<p>Ensuite, il faut modifier le serveur de son sndiod(8) pour qu&rsquo;il gère
les canaux correspondants. Par défaut, sndiod ne gère que les canaux
<code>0:1</code>, ce qui permet quand même un son stéréo.</p>
<p>En premier, vérifions la sortie SPDIF : <br>
<code># mixerctl outputs.SPDIF_source</code></p>
<p>Ce qui pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas mixerctl outputs.SPDIF_source
</span></span><span style="display:flex;"><span>outputs.SPDIF_source<span style="color:#5bc4bf">=</span>dig-dac-2:3
</span></span></code></pre></div><p>Comme le montre cet exemple, la sortie SPDIF se fait sur les canaux
<code>2:3</code> <em>(2 et 3)</em>, non géré par défaut par le serveur sndiod.</p>
<p>Il faut donc modifier le démarrage du serveur sndiod, en ajoutant les
drapeaux suivants <code>0:3</code> pour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl set sndiod flags -c0:3</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl restart sndiod</span>
</span></span></code></pre></div><p>Attention, certains périphériques matérielles (càd comme des cartes-mères)
peuvent gérer plus de canaux que les 4 premiers en question. C&rsquo;est à
chacun de s&rsquo;assurer des canaux à utiliser et à modifier en conséquence
la gestion des canaux par le serveur de son.</p>
<hr>
<h3 id="désactiver-le-bip-sonore">Désactiver le bip sonore</h3>
<p>Parfois, un bip peut être émis si par exemple une commande n’arrive pas
à être complétée avec Tab. Pour le désactiver, ajoutez cette ligne au
fichier <code>/etc/wsconsctl.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">keyboard.bell.volume</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0</span>
</span></span></code></pre></div><p>Avant OpenBSD v6.7, il pouvait être utile d&rsquo;utiliser la commande suivante :</p>
<p><code># mixerctl inputs.mix_beep = 0</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer de l&#39;audio sous OpenBSD : trucs et astuces, et divers paramétrages]]></summary>
        <published>2020-01-19T21:24:36+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3ce28999-77f6-7ace-9da4-dc00ef0aeb7e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-pdksh/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: KSH : Korn shell</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="ksh" scheme="http://doc.huc.fr.eu.org/fr/tags/ksh/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>ksh</strong> est le shell par défaut sous OpenBSD - exactement
<strong>pdksh : Public Domain Korn Shell</strong>, qui est l&rsquo;équivalent du <strong>ksh88</strong>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il ressemble beaucoup à Bash par bien des aspects et vous devriez vous y
retrouver si vous venez de GNU/Linux.</div>

<h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration principal : <code>/etc/ksh.kshrc</code></li>
<li>Votre fichier de configuration personnel : <code>~/.kshrc</code></li>
</ul>
<p>Les autres fichiers de configuration liés à l&rsquo;usage de ksh sont <em>(cf : le
<a href="https://man.openbsd.org/ksh" rel="external">manpage ksh</a>)</em> :</p>
<ul>
<li>le fichier profil de la session utilisateur : <code>~/.profile</code></li>
<li>celui relatif au système : <code>/etc/profile</code></li>
<li>la base de données shell : <code>/etc/shells</code></li>
<li>et, enfin, le fichier de profil shell privilégié : <code>/etc/suid_profile</code>
<ul>
<li><strong>ATTENTION, aux conséquences relatives aux modifications de ce
fichier sensible</strong>.</li>
</ul>
</li>
</ul>
<hr>
<p>Préférez modifier votre fichier de configuration personnel, en ajoutant
les déclarations principales, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">. /etc/ksh.kshrc</span>
</span></span></code></pre></div><h3 id="ajout-du-fichier-profile">Ajout du fichier <code>.profile</code></h3>
<p>Sourcez votre fichier personnel <code>~/.profile</code> dans lequel vous déclarez
toutes vos variables d&rsquo;environnement, vos alias, de manière généraliste.</p>
<p>Préférez l&rsquo;usage de la variable <code>HOME</code> plutôt que du
<a href="https://man.openbsd.org/ksh#Tilde_expansion" rel="external">tilde</a> <code>~</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">. $HOME/.profile</span>
</span></span></code></pre></div><h3 id="activer-lhistorique">Activer l’historique</h3>
<p>Ajoutez ceci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">HISTFILE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">~/.hist</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">HISTSIZE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">3000</span>
</span></span></code></pre></div><p>Si vous ne voulez pas garder de doublons si une même commande est lancée
plusieurs fois de suite :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">HISTCONTROL</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">ignoredumps</span>
</span></span></code></pre></div><h3 id="ps1--un-prompt-en-couleur">PS1 : un prompt en couleur</h3>
<p>⇒ PS1 user : <code>PS1=&quot;\e[0;36m\u@\h: \e[0;32m\w \e[0;36m\$ \e[m&quot;</code></p>
<p>⇒ PS1 root : <code>PS1=&quot;\e[0;31m\u@\h | \e[0;32m\w | \e[0;31m\# \e[m&quot;</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Petite astuce : si vous mettez &lsquo;#&rsquo;, à chaque commande utilisée, le
prompt affichera un compteur…</div>

<h4 id="en-fonction-du-code-de-sortie-de-la-commande">En fonction du code de sortie de la commande</h4>
<p>Il peut être intéressant d&rsquo;avoir un prompt couleur, d&rsquo;une part pour se
repérer dans son terminal, d&rsquo;autre part, ça devient intéressant
visuellement si ce dernier change de couleur en fonction du code de
retour de la commande qui vient d&rsquo;être lancée.</p>
<p>Pour cela, voici un bout de config à ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">escape</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$(print &#39;\033&#39;)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ctrla</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$(print &#39;\001&#39;)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PS1</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$(print &#39;\001\015&#39;)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PS1</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$PS1$ctrla$escape&#39;[$(($? ? 31 : 32))m&#39;$ctrla</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PS1</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$PS1&#39;[\u@\h \w]&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PS1</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$PS1$ctrla$escape&#39;[0m&#39;$ctrla&#39; &#39;</span>
</span></span></code></pre></div><h2 id="exemples">Exemples</h2>
<h3 id="un-kshrc-minimal">Un .kshrc minimal</h3>
<pre tabindex="0"><code>. /etc/ksh.kshrc
. $HOME/.profile

HISTCONTROL=ignoredumps
HISTFILE=~/.hist
HISTSIZE=3000

# Préférez paramétrer les variables PS1, LC_* dans .profile
export PS1=&#34;\u@\h:\w\$ &#34;
export LC_CTYPE=fr_FR.UTF-8
export LC_MESSAGES=fr

export TOP=&#39;-s 1&#39;
export PAGER=less
</code></pre><h2 id="informations-systèmes">Informations Systèmes</h2>
<h3 id="gestion-de-dates">Gestion de dates</h3>
<p>⇒ Obtenir une date au format timestamp :</p>
<p><code>:$ date +%s</code></p>
<p>⇒ Transformer un timestamp en date :</p>
<p><code>:$ date -r $timestamp +&quot;%x %X&quot;</code></p>
<p>⇒ Obtenir la date de maintenant :</p>
<p><code>:$ date +&quot;%x %X&quot;</code></p>
<p>⇒ Obtenir la date du jour :</p>
<p><code>:$ date +'%Y-%m-%d_%H-%M-%S'</code></p>
<p>⇒ Obtenir la date d&rsquo;hier :</p>
<p><code>:$ date -r $(($(date -j $(date +%Y%m%d1200) +%s) - 86400)) +%F</code></p>
<h3 id="informations-de-fichiers">Informations de fichiers</h3>
<h4 id="dates-de-fichier">Dates de fichier</h4>
<p>⇒ date de création : <code>:$ stat -f &quot;%c&quot; nom-fichier</code></p>
<p>⇒ date de modification : <code>:$ stat -f &quot;%m&quot; nom-fichier</code></p>
<p>⇒ date du dernier accès : <code>:$ stat -f &quot;%c&quot; nom-fichier</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Vous obtiendrez des dates au format timestamp. Pour les transformer en
date, humainement compréhensible, voire <a href="/fr/sys/openbsd/tip-pdksh/#gestion-de-dates">ci-dessus</a>…</div>

<h4 id="taille-dun-fichier">Taille d&rsquo;un fichier</h4>
<p>Obtenir la taille d&rsquo;un fichier :</p>
<p><code>:$ stat -f &quot;%z&quot; nom-fichier</code></p>
<h4 id="type-dun-fichier">Type d&rsquo;un fichier</h4>
<p>Obtenir le type du fichier :</p>
<p><code>:$ stat -f &quot;%T&quot; nom-fichier</code></p>
<h4 id="utilisateur-et-groupe-dun-fichier">Utilisateur et groupe d&rsquo;un fichier</h4>
<p>⇒ Obtenir l&rsquo;utilisateur ayant les droits sur le fichier :</p>
<p><code>:$ stat -f &quot;%u&quot; nom-fichier</code></p>
<p>⇒ et le groupe :</p>
<p><code>:$ stat -f &quot;%g&quot; nom-fichier</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Découvrir le shell par défaut sous OpenBSD : pdksh, et quelques astuces à ce propos…]]></summary>
        <published>2020-01-19T20:53:20+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:87f90d21-4cb5-fa95-b14a-f51e374b8d7d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/audacious/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Audacious / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="audacious" scheme="http://doc.huc.fr.eu.org/fr/tags/audacious/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Audacious</strong> est un lecteur multimédia qui utilise actuellement une
interface utilisateur basée sur les thémes de Winamp 2.x Il est dérivé
de BMP et XMMS.</p>
<ul>
<li>Architectures gérées : aarch64, alpha, amd64, arm, hppa, i386, mips64, mips64el, powerpc, sparc64</li>
<li>Mainteneur : l&rsquo;équipe OpenBSD</li>
<li>Openports : <a href="https://openports.pl/path/audio/audacious" rel="external">https://openports.pl/path/audio/audacious</a></li>
<li>Site officiel : <a href="http://audacious-media-player.org/" rel="external">http://audacious-media-player.org/</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 les
paquets <code>audacious audacious-plugins</code></strong> !</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le logiciel audio nommé &#39;Audacious&#39; sous OpenBSD]]></summary>
        <published>2020-01-19T20:50:12+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9c9f605b-619c-ffc0-b56e-8520a92aa45d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/lftp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: lftp : client ftp, sftp CLI / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="lftp" scheme="http://doc.huc.fr.eu.org/fr/tags/lftp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>lftp</strong>  est un outil en ligne de commande, qui permet de transférer
des fichiers. Il supporte les protocoles Bittorent, FISH, FTP, FTPS,
HTTP, HTTPS, SFTP  et a un support partiel pour WebDAV. IPv(4|6).</p>
<p>Ses fonctionnalités sont :</p>
<ul>
<li>la reconnexion automatique et la possibilité de ré-essai après erreurs
ou timeout</li>
<li>préservation de l&rsquo;heure de modification</li>
<li>mirroring, reverse mirroring, re-get, re-put</li>
<li>mise en file d&rsquo;attente par job, multiplier les transferts en tâche de
fond</li>
<li>gestion de &ldquo;bookmarks&rdquo; et d&rsquo;alias</li>
</ul>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>lftp</code>.</p>
<h2 id="utilisation">Utilisation</h2>
<p>En tant que client CLI, il peut autant s&rsquo;utiliser dans une ligne de
commande que dans un script sh.</p>
<h3 id="options">Options</h3>
<p>Les options :</p>
<ul>
<li><code>-c</code> : suivi d&rsquo;un ensemble de commandes et quitte</li>
<li><code>-d</code> : le mode de déboguage</li>
<li><code>-e</code> : suivi d&rsquo;un ensemble de commandes et ne quitte pas</li>
<li><code>-f</code> : suivi d&rsquo;un nom de fichier, permet d&rsquo;exécuter les commandes dans
ce fichier et quitte. Cette option <strong>DOIT</strong> s&rsquo;utiliser toute seule,
sans aucun autre argument (sauf <code>--norc</code>).</li>
<li><code>--norc</code> : ne pas exécuter les fichiers rc depuis votre répertoire $HOME.</li>
<li><code>-p</code> : spécifie le numéro de port sur lequel se connecter</li>
<li><code>--rcfile</code> : suivi d&rsquo;un nom de fichier, permet d&rsquo;exécuter un ensemble
de commandes dans ce fichier et d&rsquo;être exécuté plusieurs fois.</li>
<li><code>-u</code> : permet de spécifier le couple d&rsquo;identification utilisateur +
mot de passe. Il est recommandé d&rsquo;utiliser le fichier <code>~/.netrc</code> dans
lequel préciser le mot de passe, plutôt que dans la ligne de commande,
ou par le biais de la variable d&rsquo;environnement <code>LFTP_PASSWORD</code> qui
sera ensuite appelée par l&rsquo;option <code>--env-password</code>. De manière
alternative, il est possible d&rsquo;utiliser une connexion SSH par
authentification par clé autorisée.</li>
</ul>
<h3 id="variables-denvironnement">Variables d&rsquo;environnement</h3>
<p>Si les variables d&rsquo;environnement suivantes sont précisées avant l&rsquo;appel
système, <strong>lftp</strong> est/sera capable de les utiliser :</p>
<ul>
<li><code>EDITOR</code> : l&rsquo;éditeur de texte qui sera appelé lors de l&rsquo;usage de la
commande <code>edit</code>.</li>
<li><code>HOME</code> : le répertoire personnel local</li>
<li><code>LFTP_HOME</code> : utilisée pour localiser le répertoire des fichiers de
configurations locaux spécifiques à l&rsquo;utilisateur.
<ul>
<li>Par défaut, sans spécification, il sera utilisé <code>~/.lftp</code>.</li>
</ul>
</li>
<li><code>LFTP_MODULE_PATH</code> : initialise la variable <code>module:path</code></li>
<li><code>LFTP_PASSWORD</code> : utilisée par l&rsquo;argument <code>open</code> lors de l&rsquo;usage de
l&rsquo;option <code>--env-password</code>.</li>
<li><code>LS_COLORS</code> : permet de paramétrer la variable <code>color:dir-colors</code> qui
ajoutera des couleurs.</li>
<li><code>PAGER</code> : le nom du pager à utiliser lors de l&rsquo;usage des commandes
<code>more</code> et <code>zmore</code>.</li>
<li><code>SHELL</code> : utilisée par la commande <code>!</code> pour déterminer quel shell utiliser</li>
<li><code>XDG_CONFIG_HOME</code>, <code>XDG_DATA_HOME</code>, <code>XDG_CACHE_HOME</code> : utilisée pour
localiser les répertoires spécifiques utilisateur si <code>~/.lftp</code> ou la
variable d&rsquo;environnement <code>LFTP_HOME</code> ne sont pas précisés.
<ul>
<li>Par défaut, il sera recherché respectivement <code>~/.cache</code>, <code>~/.config</code>,
<code>~/.local/share</code>. Il sera ajouté le préfixe <code>/lftp</code> pour restituer
le chemin absolu du répertoire en question.</li>
</ul>
</li>
<li><code>ftp_proxy</code> : initialise la variable pour le mandataire FTP</li>
<li><code>http_proxy</code>, <code>https_proxy</code> : initialise les variables pour les
mandataires HTTP(S)</li>
<li><code>no_proxy</code> : initialise la variable <code>net:no_proxy</code>.</li>
</ul>
<h3 id="les-commandes">Les commandes</h3>
<p>ll existe énormément de commandes utilisables avec <strong>lftp</strong> ; veuillez
lire le manpage ; seules certaines seront précisées ici sur cette page :</p>
<h4 id="heading">!</h4>
<p>Cette commande spéciale <code>!</code> exécute un shell suivi d&rsquo;une autre commande</p>
<h4 id="alias">alias</h4>
<p>Pour définir un nom d&rsquo;alias ; c&rsquo;est le même principe que les alias de shell</p>
<h4 id="at">at</h4>
<p>Exécutera une commande au moment donné. Voir le manpage
<a href="https://man.openbsd.org/at" rel="external">at(1)</a>.</p>
<h4 id="edit">edit</h4>
<p>Permettra l&rsquo;édition d&rsquo;un fichier distant par le biais de l&rsquo;éditeur texte
spécifié. Dans les faits, <strong>lftp</strong> récupérera le fichier vers un répertoire
temporaire local, exécutera l&rsquo;éditeur de texte local et téléversera sur
le serveur le fichier.</p>
<p>Les options :</p>
<ul>
<li><code>-k</code> : pour garder le fichier temporaire</li>
<li><code>-o</code> : pour spécifier le répertoire temporaire</li>
</ul>
<h4 id="mirror">mirror</h4>
<p>Faire une copie en miroir d&rsquo;un répertoire source spécifié vers un
répertoire cible. <em>(c&rsquo;est l&rsquo;équivalent de l&rsquo;outil <code>rsync</code>)</em>.</p>
<p>Par défaut, la source est distante et la cible est le répertoire local.
Il faut utiliser l&rsquo;option <code>-R</code> pour inverser la source et la cible ;
ainsi le répertoire source sera le répertoire local et la cible sera le
répertoire distant.</p>
<p>Si le répertoire cible est omis, la base du nom du répertoire source sera utilisée. <br>
Si les deux sont omis, les répertoires courants local et distant seront utilisés.</p>
<p>Si le répertoire cible termine avec un <code>/</code> <em>(hormis le répertoire racine)</em>
alors la base du nom du répertoire source sera ajouté.</p>
<p>Les options :</p>
<ul>
<li><code>-a</code> : l&rsquo;équivalent des options <code>--allow-suid</code> et <code>--no-umask</code>.</li>
<li><code>-c</code>, <code>--continue</code> : continue un job si possible</li>
<li><code>-e</code>, <code>--delete</code> : supprime les fichiers qui ne sont pas présent sur
la source
<ul>
<li><code>--delete-excluded</code> : supprimera les fichiesr exclus sur la cible</li>
<li><code>--delete-first</code> : supprimera en premier les vieux fichiers avant de
transférer les nouveaux</li>
<li><code>--depth-first</code> : descendra dans les sous répertoires avant de
transférer les fichiers</li>
<li><code>--scan-all-first</code> : analysera tous les répertoires récursivement
avant de transférer les fichiers</li>
</ul>
</li>
<li><code>-F</code>, <code>--directory=</code> : fera une copie miroir du seul répertoire
spécifié, ou selon un glob précis, tel <code>/path/dir*</code>.</li>
<li><code>-f</code>, <code>--file=</code> : fera une copie miroir du seul fichier spécifié, ou
selon un glob précis, tel que <code>/path/*.txt</code>.</li>
<li><code>-I GP</code>, <code>--include-glob=GP</code> : inclue les fichiers correspondants au
glob pattern. À-propos de <code>GP</code>, voir la note ci-dessous.</li>
<li><code>-i RX</code>, <code>--include=RX</code> : inclue les fichiers correspondants à
l&rsquo;expression régulière. À-propos de <code>RX</code>, voir la note ci-dessous.</li>
<li><code>-L</code>, <code>--dereference</code> : télécharge les liens symboliques comme étant
des fichiers
<ul>
<li><code>--no-overwrite</code> : supprime d&rsquo;abord les fichiers et les recréer ensuite</li>
<li><code>--overwrite</code> : ré-écrit les fichiers sans les supprimer en premier</li>
</ul>
</li>
<li><code>-O</code>, <code>--target-directory=</code> : cible le chemin ou l&rsquo;URL</li>
<li><code>-N</code>, <code>--never-than=</code> : téléchargera seulement les fichiers les plus
récents selon une date spécifiée
<ul>
<li><code>--older-than=</code> : téléchargera seulement les fichiers  anciens selon
une date spécifiée</li>
<li><code>--size-range=</code> : téléchargera seulement les fichiers ayant telle taille</li>
</ul>
</li>
<li><code>-n</code>, <code>--only-newer</code> : téléchargera seulement les fichiers les plus
récents - dans ce cas, l&rsquo;option <code>-c</code> ne fonctionnera pas.
<ul>
<li><code>--upload-older</code> : téléchargera sur la cible même les fichiers plus
vieux que les actuels.</li>
<li><code>--transfer-all</code> : transférera tous les fichiers, même ceux qui
ressemblent à ceux existant sur la cible.</li>
</ul>
</li>
<li><code>-P</code>, <code>--parallel</code> : téléchargera N fichiers en même temps
<ul>
<li><code>--loop</code> : répétera le miroir jusqu&rsquo;à ce que plus aucun changement
ne soit trouvé</li>
<li><code>--on-change=</code> : exécutera la commande spécifiée lors d&rsquo;un changement</li>
<li><code>--use-pget</code> : utilisera l&rsquo;outil <code>pget</code> pour transférer chaque fichier</li>
</ul>
</li>
<li><code>-p</code>, <code>--no-perms</code> : ne paramétrera pas les permissions de fichiers
<ul>
<li><code>--no-umask</code> : n&rsquo;appliquera pas le mode umask</li>
</ul>
</li>
<li><code>-R</code>, <code>--reverse</code> : inverse le miroir</li>
<li><code>-r</code>, <code>--no-recursion</code> : ne parcourra pas les sous répertoires
<ul>
<li><code>--recursion=</code> : parcourra les sous répertoires selon un mode choisi</li>
<li><code>--no-symlinks</code> : ne créera pas les liens symboliques</li>
</ul>
</li>
<li><code>-s</code>, <code>--allow-suid</code> : paramétrera les bits <code>suid</code> et <code>sgid</code> selon
la source
<ul>
<li><code>--allow-chown</code> : paramétrera les droits utilisateur et groupe sur
les fichiers</li>
<li><code>--ascii</code> : utilisera le mode de transfert <code>ascii</code> - ce qui implique
l&rsquo;option <code>--ignore-size</code>.</li>
<li><code>--ignore-size</code> : ignore la taille</li>
<li><code>--ignore-time</code> : ignore l&rsquo;heure de téléchargement</li>
<li><code>--only-existing</code> : téléchargera seulement les fichiers déjà existant
sur la cible</li>
<li><code>--only-missing</code> : téléchargera seulement les fichiers non existant
sur la cible.</li>
</ul>
</li>
<li><code>-v</code>, <code>--verbose</code> : restitue les informations de manière verbeuse ; il
est possible de spécifier un niveau, tel que <code>=level</code>.
<ul>
<li><code>--log=</code> : écrit le retour des commandes <strong>lftp</strong> exécutées dans le
fichier journal spécifié</li>
<li><code>--max-errors=</code> : arrête l&rsquo;exécution après N erreurs.</li>
<li><code>--Move</code> : identique à l&rsquo;option <code>--Remove-source-dirs</code>.</li>
<li><code>--Remove-source-dirs</code> : supprime les répertoires et les fichiers
sources après le transfert - à utiliser avec précaution !</li>
<li><code>--Remove-source-files</code> : supprime les fichiers sources après le
transfert - à utiliser avec précaution !</li>
<li><code>--script=</code> : lis les commandes <strong>lftp</strong> depuis un fichier, sans les
exécuter. Autres noms de l&rsquo;option : <code>--just-print</code>, ou <code>--dry-run</code>.</li>
<li><code>--skip-noaccess</code> : ne pas essayer de transférer les fichiers qui
n&rsquo;ont pas d&rsquo;accès en lecture.</li>
<li><code>--use-cache</code> : utilise une liste de répertoire mis en cache</li>
</ul>
</li>
<li><code>-X GP</code>, <code>--exclude-glob=GP</code> : exclue les fichiers selon le pattern
glob. À-propos de <code>GP</code>, voir la note ci-dessous.
<ul>
<li><code>--exclude-glob-from=</code>, <code>--exclude-rx-from=</code>, <code>--include-glob-from=</code>,
<code>--include-rx-from=</code> : inclura ou exclura les fichiers selon le
fichier renfermant l&rsquo;expression régulière ou le glob pattern
fourni - un par ligne.</li>
</ul>
</li>
<li><code>-x RX</code>, <code>--exclude=RX</code> : exclue les fichiers selon l&rsquo;expression
régulière. À-propos de <code>RX</code>, voir la note ci-dessous.</li>
</ul>
<p>Notes  :</p>
<ul>
<li><code>GP</code> est un glob pattern à fournir, tel <code>*.zip</code></li>
<li><code>RX</code> est une expression régulière à fournir</li>
<li>sachez qu&rsquo;il existe énormément de notes relatives à certaines options,
pour plus d&rsquo;informations, veuillez lire le manpage.</li>
</ul>
<h2 id="exemples">Exemples</h2>
<h3 id="sftp">SFTP</h3>
<p>Se connecter en ligne de commande :</p>
<p><code>$ lftp -p $port sftp://$user@$address</code></p>
<ul>
<li><code>-p $port</code> : est le numéro de port de connexion vers le serveur.
<ul>
<li>Par défaut, pour <strong>SSH</strong>, c&rsquo;est le <code>22</code>, mais cela dépend de votre
configuration serveur.</li>
</ul>
</li>
<li><code>$user</code> : l&rsquo;identifiant de connexion</li>
<li><code>$adress</code> : l&rsquo;adresse ip ou le nom d&rsquo;hôte FQDN du serveur sur lequel
se connecter.</li>
</ul>
<p>Dans un script shell :</p>
<p><code>/usr/local/bin/lftp -p $port sftp://$user@$host</code></p>
<p>Une des fonctionnalités intéressantes est le fait de pouvoir faire du
&ldquo;mirroring&rdquo; - <em>de la copie en miroir d&rsquo;un ensemble de fichiers,
répertoires vers un autre endroit ; l&rsquo;équivalent de rsync</em> -</p>
<h4 id="mirroring-par-sftp">Mirroring par SFTP</h4>
<p><code>$ lftp -e &quot;mirror -e -R /repertoire_local/ /repertoire_distant/ ; quit&quot; -p $port sftp://$user@$host</code></p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>le manpage : <code>man ltfp</code></li>
<li>le site web : <a href="https://lftp.tech/" rel="external">https://lftp.tech/</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le client (s)ftp, en mode console/terminal, nommé lftp, sous OpenBSD]]></summary>
        <published>2020-01-19T17:56:42+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:abd38680-ffd8-a1bb-1b95-33bb37a8b624</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/gajim/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gajim</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Gajim" scheme="http://doc.huc.fr.eu.org/fr/tags/gajim/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://gajim.org" rel="external">Gajim</a></strong> est un client Jabber, messagerie de
communication presque instantanée, écrit en Python-GTK.</p>
<ul>
<li>Site officiel : <a href="https://gajim.org" rel="external">https://gajim.org</a></li>
<li>Site développement des plugins : <a href="https://dev.gajim.org/gajim/gajim-plugins" rel="external">https://dev.gajim.org/gajim/gajim-plugins</a></li>
</ul>
<p>Disponible : à partir d&rsquo;OpenBSD 6.2</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>gajim</code></strong>.</p>
<h3 id="plugins">Plugins</h3>
<p>Pour installer un ou plusieurs plugins, il y a :</p>
<ul>
<li>la manière officielle au-travers du gestionnaire de plugins, menu
<strong>É<u>d</u>ition &gt; P<u>l</u>ugins</strong></li>
<li>l&rsquo;autre manière étant de les télécharger à partir du site github de
développement des plugins, et de les installer dans votre répertoire
personnel local <br>
<code>~/.local/share/gajim/plugins/</code>
<ul>
<li>vous pouvez le faire en clonant le dépôt git : <br>
<code>git clone https://dev.gajim.org/gajim/gajim-plugins.git</code></li>
</ul>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Ci-dessous sera abordé les quelques plugins pour communiquer de manière
sécurisée avec un interlocuteur.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ces méthodes sont dites expérimentales !</div>

<h3 id="omemo">OMEMO</h3>
<p>Le protocole de chiffrement <strong><a href="https://conversations.im/omemo/" rel="external">OMEMO</a></strong>
est basé sur les protocoles de chiffrement X3DH <em>(génération de clés
cryptographiques asymétriques, basées soit sur XEd25519, ou XEd448 ; le
protocole XEdDSA est simplement une variante du protocole EdDSA)</em> +
&ldquo;Double Rachet&rdquo; <em>(protocole d&rsquo;échange et de maintenance des clés et
autres informations secrètes)</em>.</p>
<p>OMEMO chiffre les messages en employant AES256+GCM !</p>
<p>Les informations concernant le plugin OMEMO pour Gajim sont disponibles
depuis le wiki du git : <br>
<a href="https://dev.gajim.org/gajim/gajim-plugins/wikis/OmemoGajimPlugin" rel="external">https://dev.gajim.org/gajim/gajim-plugins/wikis/OmemoGajimPlugin</a></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Pour pouvoir utiliser OMEMO, il est nécessaire d&rsquo;avoir une version de
Gajim ≥ 0.16.6 ; ce qui est le cas depuis OpenBSD 6.0 !</div>

<hr>
<p>À noter qu&rsquo;à partir d&rsquo;OpenBSD 6.9, il est possible (et préférable)
d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 les
paquets pour les ajouter :<br>
<code>py3-cryptography py3-axolotl py3-qrcode py3-Pillow py3-future</code></p>
<p>Autrement, pour Python 2.x, une fois le plugin téléchargé et installé
dans votre répertoire personnel, en tant qu&rsquo;administrateur :</p>
<ul>
<li>Vérifiez que le paquet <code>py-cryptography</code> soit <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installé</a>

<ul>
<li><em>normalement, il l&rsquo;est en tant que dépendance de gajim !</em></li>
</ul>
</li>
<li>il est nécessaire en plus d&rsquo;installer par le bais de <code>pip</code> certains
modules supplémentaires, autrement les fonctionnalités liés à OMEMO
ne pourraient être utilisées. <br>
<code># python -m pip install python-axolotl qrcode pillow future</code></li>
</ul>
<hr>
<p>Ceci étant fait, ouvrez votre client Gajim, allez dans le menu
<strong>Édition &gt; Plugins</strong>. Activez le plugin dans l&rsquo;onglet &ldquo;Installé&rdquo;… puis
cliquer sur le bouton [ Configurer ] qui vous permettra de générer une
empreinte, pour la transmettre à un tiers, et aussi de gérer celles de
vos contacts !</p>
<h3 id="otr">OTR</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Les informations concernant le plugin <strong><a href="https://otr.cypherpunks.ca/" rel="external">OTR</a> -
Off-the-Record</strong> - pour Gajim sont disponibles depuis le wiki du git : <br>
<a href="https://dev.gajim.org/gajim/gajim-plugins/wikis/OffTheRecordPlugin" rel="external">https://dev.gajim.org/gajim/gajim-plugins/wikis/OffTheRecordPlugin</a></p>
<p>L&rsquo;auteur du plugin avertit qu&rsquo;à cause de bogues dans le plugin qui
restranscrit en text clair, il est préférable d&rsquo;utiliser soit OMEMO, soit
PGP !</p>
<p>De plus, le plugin ne fonctionnera pas si la version de Gajim est &gt;= 1.0,
car il n&rsquo;a pas été migré vers Python 3.x, et n&rsquo;est pas planifié.</p>
</div>

<h4 id="openbsd--64">OpenBSD ≤ 6.4</h4>
<p>Ceci étant fait, ouvrez votre client Gajim, allez dans le menu
<strong>Édition &gt; Plugins</strong>. Activez le plugin dans l&rsquo;onglet &ldquo;Installé&rdquo;… puis
cliquer sur le bouton [ Configurer ] qui vous permettra de générer une
empreinte, pour la transmettre à un tiers, et aussi de gérer celles de
vos contacts !</p>
<h3 id="pgp">PGP</h3>
<p>Les informations concernant le plugin <strong>PGP</strong> - pour Gajim sont
disponibles depuis le wiki du git : <br>
<a href="https://dev.gajim.org/gajim/gajim-plugins/wikis/pgpplugin" rel="external">https://dev.gajim.org/gajim/gajim-plugins/wikis/pgpplugin</a></p>
<p>Une fois le plugin téléchargé et installé dans votre répertoire personnel,
en tant qu&rsquo;administrateur :</p>
<ul>
<li>Vérifiez que le paquet <code>py-gnupg</code> soit <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installé</a>

<ul>
<li><em>normalement, il est installé en tant que dépendance de gajim !</em></li>
</ul>
</li>
</ul>
<h2 id="documentation">Documentation</h2>
<ul>
<li>ANSSI - <strong>Chiffrement de messagerie quasi instantanée : à quel protocole se vouer ?</strong> :
fichier <a href="https://www.ssi.gouv.fr/uploads/2017/10/chiffrement_messagerie_instantanee_fmaury_anssi.pdf" rel="external">pdf</a></li>
<li>LinuxFR : <a href="https://linuxfr.org/news/chatsecure-4-0-ronronne-et-adopte-omemo" rel="external">ChatSecure 4.0 ronronne et adopte OMEMO</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement de manière collaborative cette documentation
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le client Jabber, nommé Gajim, sous OpenBSD]]></summary>
        <published>2020-01-19T17:36:16+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d4b60d1e-5663-8806-3791-60a57a1044f8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/filezilla/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: FileZilla</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="FileZilla" scheme="http://doc.huc.fr.eu.org/fr/tags/filezilla/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.filezilla-project.org/" rel="external">FileZilla</a></strong> est un client FTP puissant.
Il est conçu pour être facile à utiliser et prenant en charge autant de
fonctionnalités que possible, tout en s&rsquo;efforçant d&rsquo;être rapide et fiable.</p>
<p>Les fonctionnalités principales de FileZilla sont :</p>
<ul>
<li>la capacité à reprendre des téléchargements ou téléversements (si le
serveur le supporte).</li>
<li>des commandes personnalisées.</li>
<li>un gestionnaire de site par répertoires.</li>
<li>Système Keep Alive</li>
<li>Détection des Timeout</li>
<li>Gestion des pare-feux</li>
<li>Prise en charge des SOCKS4 et 5 et du proxy HTTP1.1</li>
<li>Connexions sécurisées par SSL</li>
<li>Prise en charge de SFTP</li>
<li>Queues de téléchargement et téléversement</li>
<li>Glisser et Déposer</li>
<li>Prise en charge multi-langues</li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>filezilla</code></strong>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le puissant client FTP, nommé FileZilla, sous OpenBSD]]></summary>
        <published>2020-01-19T17:32:14+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:74510daf-8d96-28df-8fbe-bd1d7ca5957f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/avahi/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Avahi (Découverte de services multicast DNS)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Avahi" scheme="http://doc.huc.fr.eu.org/fr/tags/avahi/" />
        <category term="Zeroconf" scheme="http://doc.huc.fr.eu.org/fr/tags/zeroconf/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.avahi.org/" rel="external">Avahi</a></strong> est une implémentation libre, conforme
au standard des protocoles Multicast DNS (mDNS) et DNS-SD gérés par
Zeroconf.</p>
<p>C&rsquo;est un système qui facilite la découverte de services sur un réseau
local. Cela signifie que vous pouvez connecter votre portable ou
ordinateur sur un réseau et qu&rsquo;il soit capable instantanément de voir
les autres personnes avec qui vous pouvez discuter, trouver les
imprimantes, ou les fichiers partagés. L&rsquo;esprit de cette technologie est
toujours trouvé dans l&rsquo;Apple MacOS X (sous la marque Rendezvous, Bonjour
et parfois Zeroconf) et est très pratique.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>avahi</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Il faut :</p>
<ul>
<li>
<p><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer les services</a>

<code>multicast avahi_daemon</code></p>
<ul>
<li><strong>si <code><a class="inside" href="/fr/sys/openbsd/consolekit/" title="Lien interne vers l&#39;article : 'Consolekit2 (bus de messages) / OpenBSD'">messagebus</a>
</code>
n&rsquo;est pas activé, pensez à le faire !</span></strong></li>
</ul>
</li>
<li>
<p>que le sous-système wide D-BUS soit
<a class="inside" href="/fr/sys/openbsd/rcctl/#ordonner" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">impérativement démarré en premier</a>
 :
<code>messagebus avahi_daemon</code></p>
</li>
<li>
<p>puis <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrez les services</a>

services relatifs : <code>avahi_daemon</code></p>
</li>
</ul>
<h3 id="règles-pf">Règles PF</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Les règles PF énoncées ci-dessous sont à adapter à votre besoin !</strong></div>

<p>Voici les règles pare-feu si besoin :</p>
<ul>
<li>pour le trafic mDNS :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 224.0.0.251 port mdns allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to ff02::fb port mdns allow-opts </span>
</span></span></code></pre></div><ul>
<li>pour le trafic SSDP :
<ul>
<li>pour IPv6 :
<ul>
<li><code>ff02::c</code> est l&rsquo;adresse multicast de lien local</li>
<li><code>ff05::c</code> est l&rsquo;adresse multicast de site local</li>
<li><code>ff08::c</code> est l&rsquo;adresse multicast d&rsquo;organisation local</li>
<li>il existe aussi <code>ff0e::c</code> pour l&rsquo;adresse multicast global - //que nous n&rsquo;utiliserons pas dans le contexte local// !</li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 239.255.255.250 port ssdp allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to { ff02::c, ff05::c, ff08::c } port ssdp allow-opts </span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de lire le fichier pkg-readme :
<code>/usr/local/share/doc/pkg-readmes/avahi</code> !</p>
<p>Vous pouvez lire des exemples dans <code>/usr/local/share/examples/avahi/</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utilisons Avahi pour découvrir quels services réseaux sont disponibles sur le réseau local, sous OpenBSD]]></summary>
        <published>2020-01-19T17:08:50+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c2655384-f98e-bf1a-ca83-5ef7e73a7118</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/encfs/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: EncFS : créer et monter un Système de Fichiers virtuel Chiffré / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="encfs" scheme="http://doc.huc.fr.eu.org/fr/tags/encfs/" />
        <category term="fuse" scheme="http://doc.huc.fr.eu.org/fr/tags/fuse/" />
        <category term="OpenSSL" scheme="http://doc.huc.fr.eu.org/fr/tags/openssl/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.arg0.net/encfs" rel="external">EncFS</a></strong> fournit un système de fichiers
basés sur FUSE et OpenSSL.</p>
<p>EncFS travaille sur la base des fichiers, non pas avec des blocs
périphériques. Un système de fichiers EncFS peut grandir à n&rsquo;importe
quelle taille sans être reformaté et peut être sauvegardés sur la base
de fichiers par fichiers.</p>
<p>EncFS NE chiffre pas ou ne cache pas les informations suivantes :</p>
<ul>
<li>le nombre de fichiers que vous avez chiffrés.</li>
<li>Les permissions sur les fichiers (lecture, écriture, exécutable)</li>
<li>La taille de chaque fichier</li>
<li>La longueur approximative de chaque nom de fichier (jusqu&rsquo;à 16 octets
avec AES ou 8 octets avec Blowfish).</li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>encfs</code></strong>.</p>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est important de modifier les permissions de lecture/écriture, avec
les droits administrateur, du périphérique <strong>/dev/fuse0</strong> :</p>
<p><code># chmod 0660 /dev/fuse0</code></p>
<hr>
<p>Depuis OpenBSD 6.0, la variable système <code>kern.usermount</code> -
<em><a href="http://man.openbsd.org/OpenBSD-5.9/man3/sysctl.3" rel="external">sysctl(3)</a></em> - n&rsquo;est
plus gérée… d&rsquo;où la nécessité d&rsquo;utiliser <a href="https://man.openbsd.org/doas" rel="external"><code>doas</code>(1)</a> !</p>
</div>
<h2 id="utilisation">Utilisation</h2>
<p>Il y a trois modes de créations d&rsquo;un système de fichiers virtuel chiffré
encfs :</p>
<ul>
<li>normal</li>
<li>paranoïaque</li>
<li>expert</li>
</ul>
<hr>
<p>Pour <strong>créer</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas encfs /repertoire_chiffre /repertoire_cible 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Création du nouveau volume encrypté.
</span></span><span style="display:flex;"><span>Veuillez choisir l<span style="color:#ef6155">&#39;</span>une des options suivantes :
</span></span><span style="display:flex;"><span> entrez <span style="color:#48b685">&#34;x&#34;</span> pour le mode de configuration expert,
</span></span><span style="display:flex;"><span> entrez <span style="color:#48b685">&#34;p&#34;</span> pour le mode paranoïaque préconfiguré,
</span></span><span style="display:flex;"><span> toute autre entrée ou une ligne vide sélectionnera le mode normal.
</span></span><span style="display:flex;"><span>?&gt;
</span></span></code></pre></div><p>Choisissez d&rsquo;appuyer sur la touche :</p>
<ul>
<li>
<p><kbd>Entrée</kbd> pour utiliser le <strong>mode normal</strong></p>
</li>
<li>
<p><kbd>p</kbd> pour choisir le <strong>mode paranoïaque pré-configuré</strong></p>
<ul>
<li><em>qui est déjà correctement configuré pour un mode paranoïaque sécurisé</em>.</li>
</ul>
</li>
<li>
<p><kbd>x</kbd> est le choix du <strong>mode expert</strong></p>
<ul>
<li><em>là, il vous faudra cibler toutes les différentes options ;
à utiliser avec grande précaution</em>…</li>
<li>lire la page de manuel à ce propos !</li>
</ul>
</li>
</ul>
<p>Ensuite, l&rsquo;invite de commande vous demande de taper un mot-de-passe,
puis de le confirmer !</p>
<hr>
<p>⇒ Pour <strong>monter</strong> le système de fichier virtuel chiffré encfs, c&rsquo;est
exactement la même commande que la création :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas encfs /repertoire_chiffre /repertoire_cible
</span></span></code></pre></div><hr>
<p>⇒ Pour <strong>démonter</strong> le système de fichier virtuel chiffré encfs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas umount /repertoire_cible
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<p>Il peut arriver que, suite au montage d&rsquo;un système de fichier virtuel
encfs, les permissions d&rsquo;appartenance des fichiers et autres répertoires
sont paramétrées sur les droits administratifs de l&rsquo;utilisateur root.</p>
<p>Modifiez les, à nouveau, par vos droits utilisateurs : <br>
<code>$ chown -R $USER:$USER /repertoire_cible</code></p>
<h2 id="documentation">Documentation</h2>
<p>Il peut vous être utile de lire localement sur votre station de travail
OpenBSD, la page de manuel correspondante <code>man encfs</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer un système de fichiers virtuel, sous OpenBSD, grâce à l&#39;outil &#39;EncFS&#39;.]]></summary>
        <published>2020-01-19T17:07:59+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:36d75f18-5f23-64f3-b84c-f3e5f868ca39</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/readymedia/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: ReadyMedia (anciennement MiniDLNA)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="ReadyMedia" scheme="http://doc.huc.fr.eu.org/fr/tags/readymedia/" />
        <category term="minidlna" scheme="http://doc.huc.fr.eu.org/fr/tags/minidlna/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://sourceforge.net/projects/minidlna/" rel="external">ReadyMedia</a></strong>
<em>(anciennement nommé : <a class="inside" href="/fr/sys/openbsd/minidlna/" title="Lien interne vers l&#39;article : 'MiniDLNA (OpenBSD)'">MiniDLNA</a>
)</em>
est un simple logiciel serveur multimédia, écrit en C, qui aime être
pleinement compatible avec les clients DLNA ou UPnP-AV (télévisions,
tablettes, etc…).</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>minidlna</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Fichier de configuration : <code>/etc/minidlna.conf</code></li>
</ul>
<h3 id="avahi">Avahi</h3>
<p>L&rsquo;option <code>enable_tivo=yes</code> nécessite qu&rsquo;<a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi</a>

soit installé et configuré !</p>
<h3 id="limites-systèmes">Limites systèmes</h3>
<p>Pour améliorer la gestion des mécanismes de notification du noyau
<a href="http://man.openbsd.org/kqueue.2" rel="external">kqueue(2)</a> en temps réel, il est
intéressant d&rsquo;augmenter la variable <code>kern.maxfiles</code> gérée par
<a href="https://man.openbsd.org/sysctl.8" rel="external">sysctl(8)</a>, soit en l&rsquo;ajoutant au
fichier de configuration <code>/etc/</code><a href="https://man.openbsd.org/sysctl.conf.5" rel="external"><code>sysctl.conf(5)</code></a>,
soit en modifiant les classes de <a href="https://man.openbsd.org/login.1" rel="external">login(1)</a>
en augmentant les limites d&rsquo;ouvertures de fichiers <code>cur</code> et <code>max</code> du
fichier <code>/etc/</code><a href="https://man.openbsd.org/login.conf.5" rel="external"><code>login.conf(5)</code></a>.</p>
<p>Ce qui peut donner, par exemple :</p>
<ul>
<li>pour le fichier <code>/etc/sysctl.conf</code> : <code>kern.maxfiles=16384</code></li>
<li>pour le fichier <code>/etc/login.conf</code> : <br></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>  <span style="color:#06b6ef">minidlna:\</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">:openfiles</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">16384:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    :tc=daemon: &lt;/file&gt;</span>
</span></span></code></pre></div><p>Une fois fait, <strong>redémarrez votre machine</strong> !</p>
<h3 id="règles-pf">Règles PF</h3>
<p>Voici un exemple de règles PF, à modifier selon vos besoins :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto tcp from egress:network to egress port 8200 flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto udp from egress:network to egress port 8200 allow-opts keep state</span>
</span></span></code></pre></div><p>Il vous sera aussi nécessaire d&rsquo;ajouter celles relatives à
<a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi</a>
, si besoin…</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="too-many-open-files">Too many open files</h3>
<p>Depuis OpenBSD 6.5, le fonctionnement de minidlna a changé. Ceci est
expliqué dans la section &ldquo;<a href="/fr/sys/openbsd/readymedia/#limites-systèmes">Limites systèmes</a>&rdquo;.
Malgré le paramétrage indiqué dans ladite section, il peut être nécessaire
de paramétrer l&rsquo;option <code>inotify</code> sur <code>no</code> dans le fichier de configuration
de minidlna :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># set this to no to disable kqueue monitoring to automatically discover new files</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># note: the default is yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inotify</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">no</span>
</span></span></code></pre></div><p>Puis, <a class="inside" href="/fr/sys/openbsd/rcctl/#red%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">redémarrez le service</a>
 de minidlna.</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Veuillez lire le fichier : <code>/usr/local/share/doc/pkg-readmes/minidlna</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le serveur de contenu multimédia, nommé ReadyMedia, sous OpenBSD]]></summary>
        <published>2020-01-19T16:53:16+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a5afb183-39fb-725e-069d-006fac012658</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tutoriel-openbsd-cvs/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [Mini-Tuto] Utiliser CVS sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="cvs" scheme="http://doc.huc.fr.eu.org/fr/tags/cvs/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le projet OpenBSD diffuse ses sources, quelqu&rsquo;elles soient, par le biais
de <a href="https://www.openbsd.org/cvsync.html" rel="external">serveurs Anonymes CVS</a> - qui
est un système de gestion des différentes versions d&rsquo;un code
<em>(tel que peut l&rsquo;être git, ou bazaar…)</em></p>
<p>Ayant une machine informatique sous OpenBSD, nous n&rsquo;avons besoin de ne
rien installer, puisque <code>cvs</code> est installé par défaut.</p>
<p>Le projet OpenBSD a 4 dépôts différents, avec lesquels nous pouvons interagir :</p>
<ul>
<li><strong>src</strong> - code source pour le système de base</li>
<li><strong>ports</strong> - l&rsquo;arborescence des ports</li>
<li><strong>www</strong> - web pages</li>
<li><strong>xenocara</strong> - xenocara</li>
</ul>
<p><em>Ces dépôts, du fait de ne pas faire partie de l&rsquo;équipe des développeurs,
nous sont accessibles seulement en lecture seule !</em></p>
<h2 id="récupération-des-sources">Récupération des sources</h2>
<p>Admettons que nous avons repéré une erreur sur une des pages du site web
d&rsquo;OpenBSD, nous &ldquo;interagirons&rdquo; donc avec le dépôt <strong>www</strong>.</p>
<p>Commençons par créer un répertoire où nous téléchargerons les sources
désirées :</p>
<p><code>$ mkdir ~/src &amp;&amp; cd ~/src</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Bien sûr, le dossier peut avoir tout autre nom que vous désirez lui
donner… par convention, nous utiliserons &ldquo;~/src&rdquo; pour le reste de ce
mini-tutoriel !</div>

<p>Puis, demandons à cvs de récupérer les sources désirées - nous
choisissons pour l&rsquo;exemple le <a href="https://www.openbsd.org/anoncvs.html" rel="external">serveur anonyme CVS</a>
de nos collaborateurs français que sont A.Jacoutot et L.Breuil :</p>
<p><code>$ cvs -qd anoncvs@anoncvs.fr.openbsd.org:/cvs get -P www</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Patientez, cela mettra un certain temps pour récupérer l&rsquo;ensemble des
fichiers sources mis à disposition, selon votre bande passante !</div>

<h2 id="modification">Modification</h2>
<ul>
<li>Éditez le fichier où vous pensez avoir trouvé une erreur pour le
corriger, avec votre éditeur texte préféré.</li>
<li>Puis, créer un fichier diff :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cd ~/src/www
</span></span><span style="display:flex;"><span>$ cvs diff -u &gt; /tmp/patch.txt
</span></span></code></pre></div><p>Cela étant fait, transmettez le contenu du fichier <code>patch.txt</code>, intégré
dans le corps du mail - en copie - de préférence à la liste de diffusion
<a href="mailto:tech@openbsd.org" rel="external">tech@openbsd.org</a> !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention, pour les trois autres dépôts que sont &ldquo;src&rdquo;, &ldquo;ports&rdquo; et
&ldquo;xenocara&rdquo;, l&rsquo;utilisation de CVS est légèrement différente ; tout est
assez bien expliqué… dans la page &ldquo;<a href="https://www.openbsd.org/cvsync.html" rel="external">CVS Anonyme</a>&rdquo; !</div>

<h2 id="mettre-à-jour-votre-arborescence-des-sources">Mettre à jour votre arborescence des sources</h2>
<p>Pour mettre à jour l&rsquo;arborescence que vous avez déjà récupérée, c&rsquo;est
vraiment très simple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cd ~/src/www
</span></span><span style="display:flex;"><span>$ cvs -q up -Pd
</span></span></code></pre></div><h2 id="gestion-derreurs">Gestion d&rsquo;erreurs</h2>
<h3 id="no-cvsroot-specified">No CVSROOT specified</h3>
<p>Vous avez l&rsquo;erreur suivante, quand vous utilisez cvs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cvs update: No CVSROOT specified!  Please use the <span style="color:#48b685">`</span>-d<span style="color:#ef6155">&#39;</span> option
</span></span><span style="display:flex;"><span>cvs <span style="color:#5bc4bf">[</span>update aborted<span style="color:#5bc4bf">]</span>: or set the CVSROOT environment variable.
</span></span></code></pre></div><p><strong>Vous n&rsquo;êtes pas dans le bon répertoire à mettre à jour</strong> - déplacez-vous
dans le répertoire cible à mettre à jour.</p>
<p>Admettons, pour reprendre l&rsquo;exemple de gestion du site www, mettez-vous
dans <code>~/src/www</code> !!!</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comprendre le fonctionnement de CVS par le biais de ce mini-tutoriel pour collaborer avec l&#39;équipe d&#39;OpenBSD]]></summary>
        <published>2020-01-19T16:44:06+02:00</published>
        <updated>2023-05-10T16:56:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:fc0cb040-9449-1769-0049-ad6bec01aff5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/mediatomb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Mediatomb</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="mediatomb" scheme="http://doc.huc.fr.eu.org/fr/tags/mediatomb/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>MediaTomb est LE serveur Multimedia UPnP OpenSource.</p>
<p>Site : <a href="http://mediatomb.cc/" rel="external">http://mediatomb.cc/</a></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><span em>N&rsquo;est plus disponible ni en tant que paquet, ni en tant que
port depuis OpenBSD 6.4 !</span></p>
<p>Veuillez migrer sur un autre service multimédia supporté, tel que
<a class="inside" href="/fr/sys/openbsd/readymedia/" title="Lien interne vers l&#39;article : 'ReadyMedia (anciennement MiniDLNA)'">ReadyMedia</a>
!</p>
</div>

<ul>
<li>v6.3 : mediatomb-0.12.1p18</li>
<li>v6.2 : mediatomb-0.12.1p16</li>
<li>v6.1 : mediatomb-0.12.1p14</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Était installable depuis le système de package : <code>mediatomb</code></p>
<h2 id="configuration">Configuration</h2>
<ul>
<li>Fichier de configuration : <code>/etc/mediatomb/config.xml</code></li>
</ul>
<p>Après toute modification, pensez à relancer le serveur !</p>
<h3 id="gestion-des-accès">Gestion des accès</h3>
<p>Il est impératif d&rsquo;empêcher toute connexion non désirée à l&rsquo;interface
web d&rsquo;administration !</p>
<p>Ouvrir le fichier de configuration, pour modifier les lignes suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;accounts</span> <span style="color:#06b6ef">enabled=</span><span style="color:#48b685">&#34;no&#34;</span> <span style="color:#06b6ef">session-timeout=</span><span style="color:#48b685">&#34;30&#34;</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;account</span> <span style="color:#06b6ef">user=</span><span style="color:#48b685">&#34;mediatomb&#34;</span> <span style="color:#06b6ef">password=</span><span style="color:#48b685">&#34;mediatomb&#34;</span><span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#5bc4bf">&lt;/accounts&gt;</span>
</span></span></code></pre></div><p>On change la valeur de l&rsquo;attribut <code>enabled</code> par <code>yes</code> puis celles des
attributs <code>user</code> et <code>password</code>, par celles que vous désirez utiliser.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne laissez pas les valeurs par défaut concernant les attributs <code>user</code> et
<code>password</code> !</div>

<h3 id="encodage-utf-8">Encodage UTF-8</h3>
<p>L&rsquo;encodage UTF-8 n&rsquo;est pas géré nativement.</p>
<p>Ouvrir le fichier de configuration, après la balise ouvrante <code>import</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;import</span> <span style="color:#06b6ef">hidden-files=</span><span style="color:#48b685">&#34;no&#34;</span><span style="color:#5bc4bf">&gt;</span>
</span></span></code></pre></div><p>Puis, ajoutez les lignes suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;filesystem-charset&gt;</span>UTF-8<span style="color:#5bc4bf">&lt;/filesystem-charset&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;metadata-charset&gt;</span>UTF-8<span style="color:#5bc4bf">&lt;/metadata-charset&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;playlist-charset&gt;</span>UTF-8<span style="color:#5bc4bf">&lt;/playlist-charset&gt;</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[mediatomb : un serveur multimédia sous OpenBSD]]></summary>
        <published>2020-01-19T16:34:04+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ae7e05e7-d6e9-a127-aa0a-8826c1642898</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/syspatch/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Syspatch : gérer les correctifs binaires du système de base sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="syspatch" scheme="http://doc.huc.fr.eu.org/fr/tags/syspatch/" />
        <content type="html"><![CDATA[<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/syspatch/#man-8-syspatch">man 8 syspatch</a></li>
</ul>
<h3 id="man-8-syspatch">man 8 syspatch</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>syspatch</strong> [<strong>-c</strong> | <strong>-l</strong> | <strong>-R</strong> | <strong>-r</strong>]</p>
<h4 id="description">Description</h4>
<p><strong>Syspatch</strong> est un outil pour récupérer, vérifier et installer, voire
revenir à une précédente version, des correctifs de binaire d&rsquo;OpenBSD.</p>
<p>Lorsqu&rsquo;il est exécuté sans aucune option, syspatch appliquera tous les
correctifs non installés, créant une archive pour revenir en arrière,
contenant les fichiers qui vont être remplacés, puis extrait et installe
tous les fichiers contenus dans l&rsquo;archive pour syspatch. Les correctifs
sont cumulatifs et en tant que tel, il n&rsquo;est pas possible de les installer
un par un.</p>
<p>Les options sont les suivantes :</p>
<ul>
<li><strong><code>-c</code></strong> : liste les correctifs disponibles ; convient pour <a href="https://man.openbsd.org/cron.8" rel="external">cron(8)</a>.</li>
<li><strong><code>-l</code></strong> : liste les correctifs appliqués</li>
<li><strong><code>-R</code></strong> : enlever tous les correctifs</li>
<li><strong><code>-r</code></strong> : enlever les correctifs récemment installés</li>
</ul>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><code>/etc/installurl</code> : URL du miroir d&rsquo;OpenBSD pour récupérer les correctifs.</li>
<li><code>/var/syspatch/*</code> : répertoires contenant les archives de reversion
et originales, signées avec <a href="https://man.openbsd.org/diff" rel="external">diff(1)</a>
et les correctifs installés.</li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="https://man.openbsd.org/signify" rel="external">signify(1)</a>, <a href="https://man.openbsd.org/installurl.5" rel="external">installurl(5)</a>, <a href="https://man.openbsd.org/release.8" rel="external">release(8)</a></li>
</ul>
<h4 id="histoire">Histoire</h4>
<p><strong>syspatch</strong> est apparu la première fois dans OpenBSD 6.1</p>
<h4 id="auteurs">Auteurs</h4>
<p><strong>syspatch</strong> a été écrit par Antoine Jacoutot <a href="mailto:ajacoutot@openbsd.org" rel="external">ajacoutot@openbsd.org</a>.</p>
<h4 id="mise-en-garde">Mise en garde</h4>
<p><strong>syspatch</strong> est conçu pour travailler seulement sur les versions d&rsquo;un
OpenBSD officiel.</p>
<hr>
<p><em>Traduction du manpage <a href="https://man.openbsd.org/syspatch" rel="external">syspatch(8)</a> !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer correctement les correctifs sous OpenBSD, grâce à l&#39;outil &#39;syspatch&#39;.]]></summary>
        <published>2020-01-19T16:30:57+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:469bab96-974b-4976-55e0-b39a00e0835e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/rcctl/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: rcctl : configurer et contrôler les services sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="rcctl" scheme="http://doc.huc.fr.eu.org/fr/tags/rcctl/" />
        <content type="html"><![CDATA[<h2 id="utilisation">Utilisation</h2>
<p>Pour rappel, voici les usages les plus courants :</p>
<h3 id="activer">Activer</h3>
<ul>
<li><code>rcctl enable service</code></li>
</ul>
<h3 id="désactiver">Désactiver</h3>
<ul>
<li><code>rcctl disable service</code></li>
</ul>
<h3 id="démarrer">Démarrer</h3>
<ul>
<li><code>rcctl start service</code></li>
</ul>
<h3 id="redémarrer">Redémarrer</h3>
<ul>
<li><code>rcctl restart service</code></li>
</ul>
<h3 id="recharger">Recharger</h3>
<ul>
<li><code>rcctl reload service</code></li>
</ul>
<h3 id="arrêter">Arrêter</h3>
<ul>
<li><code>rcctl stop service</code></li>
</ul>
<h3 id="paramétrer">Paramétrer</h3>
<p>Pour configurer un service avec certains drapeaux au démarrage de celui-ci :</p>
<ul>
<li><code>rcctl set service flags nom_drapeau valeur_drapeau…</code></li>
</ul>
<p>Il peut y avoir sans soucis plusieurs drapeaux et leurs valeurs se suivant,
sans soucis.</p>
<p>Pour connaître les noms des drapeaux d&rsquo;un service, il est impératif de
lire le manpage correspondant.</p>
<h3 id="ordonner">Ordonner</h3>
<p>Certains services doivent démarrés avant d&rsquo;autres, il faut donc les spécifier
les uns devant les autres :</p>
<ul>
<li><code>rcctl order service1 service2 service…</code></li>
</ul>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/rcctl/#man-8-rcctl">man 8 rcctl</a></li>
</ul>
<h3 id="man-8-rcctl">man 8 rcctl</h3>
<h4 id="synopsis">Synopsis</h4>
<ul>
<li><strong>rcctl</strong>     <strong>get</strong>|<strong>getdef</strong>|<strong>set</strong> <strong>service</strong> | <strong>daemon</strong> [<strong>variable</strong> [<strong>arguments</strong>]]</li>
<li><strong>rcctl</strong>     [<strong>-df</strong>] <strong>action daemon</strong> <strong>…</strong></li>
<li><strong>rcctl</strong>     <strong>disable</strong>|<strong>enable</strong>|<strong>order</strong> [<strong>daemon</strong> <strong>…</strong>]</li>
<li><strong>rcctl</strong>     <strong>ls</strong> <strong>lsarg</strong></li>
</ul>
<h4 id="description">Description</h4>
<p>L&rsquo;utilitaire <strong>rcctl</strong> peut activer ou désactiver un <strong>service</strong> du système
de base ou un <strong>démon</strong> d&rsquo;un paquet dans <a href="http://man.openbsd.org/rc.conf.local.8" rel="external">rc.conf.local(8)</a>
ou afficher sa configuration et son statut. Pour un <strong>démon</strong>, il peut
aussi changer les arguments de ligne de commande, l&rsquo;utilisateur avec
lequel l&rsquo;exécuter, le délai &ldquo;timeout&rdquo; d&rsquo;action de <a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a>
ou appeler son script de contrôle du démon <a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a>.</p>
<p>Les commandes suivantes sont disponibles
<em>(<strong>variable</strong> peut être de type <strong>class</strong>, <strong>flags</strong>, <strong>status</strong>, <strong>timeout</strong> ou <strong>user</strong>)</em> :</p>
<ul>
<li>[<strong>-df</strong>] action daemon <strong>…</strong> : exécute les scripts du <strong>démon</strong>
<a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a> avec l&rsquo;argument <strong>action</strong>,
passant par dessus les options spécifiées, s&rsquo;il y en a.</li>
<li><strong>disable</strong> <strong>service</strong> <strong>…</strong> | <strong>daemon</strong> <strong>…</strong> : alias de <strong>set</strong> <strong>service</strong>|<strong>daemon</strong> <strong>status off</strong>.</li>
<li><strong>enable</strong> <strong>service</strong> <strong>…</strong> | <strong>daemon</strong> <strong>…</strong> : alias de <strong>set</strong> <strong>service</strong>|<strong>daemon</strong> <strong>status on</strong>.</li>
<li><strong>get</strong> <strong>service</strong> | <strong>daemon</strong> [<strong>variable</strong>] : affiche la valeur
du <strong>service</strong> ou <strong>démon</strong>. Si <strong>variable</strong> est vide, affiche toutes
les variables et valeurs du <strong>service</strong> ou du <strong>démon</strong> dans un format
compatible avec <a href="http://man.openbsd.org/rc.conf.8" rel="external">rc.conf(8)</a>. <br>
Lorsque <strong>daemon</strong> est paramétré sur &ldquo;al&rdquo;, <strong>variable</strong> ne doit pas
être configurée et <strong>rcctl</strong> affichera toutes les variables des
services et démons.</li>
<li><strong>getdef</strong> <strong>service</strong> | <strong>daemon</strong> [<strong>variable</strong>] : tout comme get
mais retourne les valeurs par défaut.</li>
<li><strong>ls</strong> <strong>lsarg</strong> : affiche une liste de services et démons correspondant
à <strong>lsarg</strong>, qui peut être un des suivants :
<ul>
<li><strong>all</strong> : tous les services et démons</li>
<li><strong>failed</strong> : les démons activés mais arrêtés</li>
<li><strong>off</strong> : les services et démons désactivés</li>
<li><strong>on</strong> : les services et démons activés</li>
<li><strong>started</strong> : les démons fonctionnant</li>
<li><strong>stopped</strong> : les démons stoppés</li>
</ul>
</li>
<li><strong>order</strong> [<strong>daemon</strong> <strong>…</strong>] : place les démons du paquet spécifiés
au commencement de <strong>pkg_scripts</strong>. Ils doivent être toujours activés. <br>
Si aucun démon n&rsquo;est spécifié, affiche l&rsquo;ordre actuel. <br>
La commande <strong>order</strong> est seulement nécessaire après l&rsquo;activation
d&rsquo;un démon qui a besoin d&rsquo;être exécuté avant un ou plusieurs démons
déjà actifs. Spécifiez le nouveau démon précédé de tout ceux qui doivent
être exécutés avant lui, mais pas de ceux qui en dépendent.</li>
<li><strong>set</strong> <strong>service</strong> | <strong>daemon variable</strong> [<strong>arguments</strong>] : Pour un
démon, configure la variable du démon avec les arguments spécifiés.
Si <strong>variable</strong> est déjà paramétrée, la variable du démon est reconfigurée
par les arguments fournis en option ou sa valeur par défaut. <br>
Le <strong>status</strong> <strong>variable</strong> doit être fourni avec un argument <strong>on</strong>
ou <strong>off</strong>. Il est utilisé pour activer ou désactiver un <strong>service</strong>
ou <strong>démon</strong> dans <a href="http://man.openbsd.org/rc.conf.local.8" rel="external">rc.conf.local(8)</a>.
Quand un démon désactivé d&rsquo;un paquet est activé, il est ajouté à la
fin de <strong>pkg_scripts</strong>. Quand un démon d&rsquo;un paquet est désactivé, il
est supprimé de <strong>pkg_scripts</strong> et ses variables sont supprimées,
s&rsquo;il y en a.</li>
</ul>
<h4 id="statut-de-sortie">Statut de sortie</h4>
<p><strong>rcctl</strong> <strong>action</strong> retourne un statut de sortie du script du démon
<a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a>. <br>
<strong>rcctl get</strong> <strong>daemon</strong> | <strong>service</strong> [<strong>status</strong>] termine avec 0 si le
démon ou service est activé et avec 1 s&rsquo;il ne l&rsquo;est pas.  <br>
<strong>rcctl getdef</strong> <strong>daemon</strong> | <strong>service</strong> [<strong>status</strong>] termine avec 0 si
le démon ou service est activé par défaut et 1 s&rsquo;il ne l&rsquo;est pas. <br>
<strong>rcctl ls failed</strong> termine avec 1 si un démon activé ne fonctionne pas.
Autrement, l&rsquo;utilitaire <strong>rcctl</strong> termine avec 0 en cas de succès, et
supérieur à 0 si une erreur arrive (2 indique un démon ou service non existant).</p>
<h4 id="exemples">Exemples</h4>
<p>Active et paramètre les drapeaux d&rsquo;<a href="http://man.openbsd.org/apmd.8" rel="external">apmd(8)</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl set apmd status on</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set apmd flags -A</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl get apmd</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">apmd_class</span><span style="color:#5bc4bf">=</span>daemon
</span></span><span style="display:flex;"><span><span style="color:#ef6155">apmd_flags</span><span style="color:#5bc4bf">=</span>-A
</span></span><span style="display:flex;"><span><span style="color:#ef6155">apmd_rtable</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">apmd_timeout</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">30</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">apmd_user</span><span style="color:#5bc4bf">=</span>root
</span></span><span style="display:flex;"><span><span style="color:#776e71"># echo $?</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">0</span>
</span></span></code></pre></div><p>La manière recommandée pour exécuter une seconde copie d&rsquo;un démon en particulier
pour un but différent est de créer un lien symbolique vers son script de
contrôle <a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># ln -s /etc/rc.d/snmpd /etc/rc.d/snmpd6</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set snmpd6 status on</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set snmpd6 flags -D addr=2001:db8::1234</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start snmpd6</span>
</span></span></code></pre></div><h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="http://man.openbsd.org/rc.conf.local.8" rel="external">rc.conf.local(8)</a>, <a href="http://man.openbsd.org/rc.d.8" rel="external">rc.d(8)</a></li>
</ul>
<h4 id="histoire">Histoire</h4>
<p><strong>rcctl</strong> est apparu la première fois dans OpenBSD 5.7.</p>
<h4 id="auteurs">Auteurs</h4>
<p><strong>rcctl</strong> a été écrit par Antoine Jacoutot <a href="mailto:ajacoutot@openbsd.org" rel="external">ajacoutot@openbsd.org</a>.</p>
<hr>
<p><em>Traduction du manpage <a href="http://man.openbsd.org/man8/rcctl.8" rel="external">rcctl(8)</a> !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Contrôler les services sous OpenBSD grâce à l&#39;outil de gestion &#39;rcctl&#39;.]]></summary>
        <published>2020-01-19T16:30:51+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:db5fb422-5778-0575-917e-74640e3bd904</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/ntpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: NTPD : Serveur de temps</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="ntp" scheme="http://doc.huc.fr.eu.org/fr/tags/ntp/" />
        <category term="OpenNTPD" scheme="http://doc.huc.fr.eu.org/fr/tags/openntpd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><a href="http://www.openntpd.org/" rel="external">OpenNTPD</a> est intégré nativement dans OpenBSD.</p>
<h2 id="serveurs-ntp">Serveurs NTP</h2>
<p>Les adresses de serveurs NTP sont visibles depuis la
<a href="http://support.ntp.org/bin/view/Servers/WebHome#Finding_A_Time_Server" rel="external">page pour trouver un serveur</a>.</p>
<p>Les <a href="http://support.ntp.org/bin/view/Servers/NTPPoolServers" rel="external">serveurs de pool NTP</a>
sont par zones mondiales comportant plusieurs pays.</p>
<ul>
<li>La zone Europe se gère à partir des serveurs [[http://www.pool.ntp.org/zone/europe|europe.pool.ntp.org]].</li>
<li>La zone relative à la France est : [[http://www.pool.ntp.org/zone/fr|fr.pool.ntp.org]]</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration est <code>/etc/ntpd.conf</code>.</p>
<p>Il est apparu dans OpenBSD 3.6.</p>
<p>Des différentes options :</p>
<ul>
<li><strong>listen on</strong> <em>address</em> [<strong>rtable</strong> <em>table-id</em>] : spécifie l&rsquo;adresse
ip locale ou le nom d&rsquo;hôte que doit écouter le service ntpd(8). Si
l&rsquo;option est spécifiée plusieurs fois, le service écoutera chacune
des adresses données. Si le symbole <code>*</code> est donné, ntpd écoutera toutes
les adresses locales où est spécifiée la table de routage. <br>
Le mot-clé <code>rtable</code> indique quelle table de routage écouter. <br>
Par défault, ntpd écoute la table de routage en cours.</li>
<li><strong>query from</strong> <em>address</em> : spécifie l&rsquo;adresse IP locale que le démon
ntpd(8) doit utiliser pour les requêtes sortantes vers des serveurs
spécifiés ultérieurement.</li>
<li><strong>sensor</strong> <em>device</em> : spécifie un périphérique d&rsquo;écoute de temps que
ntpd(8) doit écouter. S&rsquo;ils sont spécifiés plusieurs fois, ntpd utilisera
chaque capteur donné en référence qui existe vraiment ; ceux qui sont
inexistants sont ignorés. <br>
Si le symbole <code>*</code> est donné, ntpd essaiera d&rsquo;écouter tous les capteurs
qu&rsquo;il trouvera. <br>
Par défaut, ntpd n&rsquo;utilise aucun capteur.</li>
<li><strong>server</strong> <em>address</em> [<strong>weight</strong> <em>weight-value</em>] : spécifie l&rsquo;adresse
IP ou le nom d&rsquo;hôte d&rsquo;un serveur NTP à synchroniser. ntpd essaiera de
se synchroniser sur tous les serveurs spécifiés, si cette option est
utilisée plusieurs fois. Si un nom d&rsquo;hôte fonctionne sur la double
couche réseau IPv4|6, ntpd utilisera la première adresse réseau. <br>
Si ntpd n&rsquo;a pas de réponse d&rsquo;une adresse, il utilisera la suivante
jusqu&rsquo;à ce qu&rsquo;une réponde. <br>
Il est recommandé de configurer plusieurs serveurs, de préférence des
serveurs à faible latence, afin d&rsquo;obtenir une meilleure précision.</li>
<li><strong>servers</strong> <em>address</em> [<strong>weight</strong> <em>weight-value</em>] : identique à
l&rsquo;option <code>server</code>, à la différence que si les serveurs ont plusieurs
adresses IP, ntpd essaiera de se synchroniser sur toutes ces adresses.</li>
<li><strong>constraint from</strong> <em>url</em> : spécifie une URL, l&rsquo;adresse IP ou le nom
d&rsquo;hôte d&rsquo;un serveur HTTPS pour fournir une contrainte. <br>
Si la contrainte donnée est utilisée plus d&rsquo;une fois, ntpd(8) calculera
une contrainte médiane à partir de tous les serveurs spécifiés.</li>
<li><strong>constraints from</strong> <em>url</em> : identique à l&rsquo;option <code>constraint from</code>,
à la différence que si le nom d&rsquo;hôte est résolu sur plusieurs adresses
IP, ntpd(8) calculera une contrainte médiane à partir de toutes ces
adresses.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p><strong>À-propos des options de contraintes</strong> :<br>
ntpd(8) peut être configuré pour interroger la &lsquo;Date&rsquo; des serveurs HTTPS
de confiance via TLS. Cette information de temps n&rsquo;est pas utilisée pour
la précision mais agit comme une contrainte authentifiée, réduisant ainsi
l&rsquo;impact des attaques NTP non authentifiées de l&rsquo;homme au milieu.
Les paquets NTP reçus dont les informations temporelles se situent en
dehors d&rsquo;une plage proche de la contrainte seront rejetés et ces serveurs
NTP seront marqués comme invalides.</p>
<hr>
<p>Dans ce <a href="https://marc.info/?l=openbsd-misc&amp;m=158888999317454&amp;w=2" rel="external">mail</a>,
Theo de Raadt explique pourquoi il n&rsquo;est pas désirable de personnaliser
les paramètres de contraintes autrement que ceux que l&rsquo;équipe fixe. <br>
Où l&rsquo;on apprend aussi que le domaine <strong><a href="https://www.openbsd.org" rel="external">www.openbsd.org</a></strong> ne doit pas être
invoqué, non plus…</p>
</div>

<h3 id="exemple">Exemple</h3>
<p>Voici un exemple du fichier <code>/etc/examples/ntpd.conf</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: ntpd.conf,v 1.5 2019/11/11 16:44:37 deraadt Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sample ntpd configuration file, see ntpd.conf(5)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Addresses to listen on (ntpd does not listen by default)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#listen on *</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sync to a single server</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#server ntp.example.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a random selection of NTP Pool Time Servers</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># see http://support.ntp.org/bin/view/Servers/NTPPoolServers</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers pool.ntp.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># time server with excellent global adjacency</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server time.cloudflare.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a specific local timedelta sensor (radio clock, etc)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">sensor nmea0 trusted</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use all detected timedelta sensors</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sensor *</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># get the time constraint from a well-known HTTPS site</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraint from &#34;9.9.9.9&#34;		# quad9 v4 without DNS</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraint from &#34;2620:fe::fe&#34;		# quad9 v6 without DNS</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraints from &#34;www.google.com&#34;	# intentionally not 8.8.8.8</span>
</span></span></code></pre></div><h2 id="service-ntpd">Service NTPD</h2>
<p>Le démon <code>ntpd</code> synchronise l&rsquo;horloge locale sur un ou plusieurs serveurs
NTP distants ou capteurs timedelta locaux. ntpd peut également agir comme
un serveur NTP lui-même, redistribuant l&rsquo;heure locale. Il implémente la
version 4 de Simple Network Time Protocol, telle que décrite dans la RFC
5905, et la version 3 de Network Time Protocol, telle que décrite dans
la RFC 1305. Le temps peut également être récupéré depuis les serveurs
HTTPS pour réduire l&rsquo;impact des attaques NTP dites &ldquo;man-in-the-middle&rdquo;
(<em>l&rsquo;homme au milieu</em>) non authentifiées.</p>
<p>Le service <code>ntpd</code> est apparu la première fois dans OpenBSD 3.6.</p>
<p>Les options possibles au service sont :</p>
<ul>
<li><code>-d</code> : ne pas mettre en service. ntpd fonctionnera alors en arrière plan,
et journalisera vers la sortie <code>stderr</code>.</li>
<li><code>-f *fichier*</code> : utilisera le fichier de configuration spécifié au lieu
du fichier de configuration par défaut.</li>
<li><code>-n</code> : test la validité du fichier de configuration. À n&rsquo;utiliser que
pour cela.</li>
<li><code>-S</code> : annule les effets de l&rsquo;option <code>-s</code>.</li>
<li><code>-s</code> : essaye toujours de régler l&rsquo;heure au démarrage de la machine.
Par défaut, ntpd essaye de régler l&rsquo;heure au démarrage, uniquement
si les contraintes sont configurées et satisfaites. ntpd restera au
premier plan jusqu&rsquo;à 15 secondes en attendant la réponse d&rsquo;un des
serveurs NTP configurés.</li>
</ul>
<h2 id="le-contrôleur-ntpctl">Le Contrôleur ntpctl</h2>
<p>Le contrôleur <code>ntpctl</code> est un programme qui affiche les informations liées
au service ntpd(8).</p>
<p>Les options possibles sont :</p>
<ul>
<li><code>-s all | peers | Sensors | status</code> :
<ul>
<li><code>all</code> : affiche toutes les informations possibles</li>
<li><code>peers</code> : affiche les informations relatives à chaque pair</li>
<li><code>Sensors</code> : affiche les informations relatives à chaque capteur.</li>
<li><code>status</code> : indique l&rsquo;état des pairs et des capteurs, et si l&rsquo;horloge du système est synchronisée.</li>
</ul>
</li>
</ul>
<p>Le contrôleur est apparu la première fois dans OpenBSD 5.5.</p>
<hr>
<h2 id="documentation">Documentation</h2>
<p>⇒ les différents manpage :</p>
<ul>
<li>le service <a href="http://man.openbsd.org/ntpd.8" rel="external">ntpd(8)</a>.</li>
<li>le contrôleur <a href="http://man.openbsd.org/ntpctl.8" rel="external">ntpdctl(8)</a>.</li>
<li>le fichier de configuration <a href="http://man.openbsd.org/ntpd.conf.5" rel="external">ntpd.conf</a>.</li>
<li>un exemple local : <code>/etc/examples/ntpd.conf</code></li>
<li>RFC 1305 : <a href="https://tools.ietf.org/html/rfc1305" rel="external">https://tools.ietf.org/html/rfc1305</a> ;
<ul>
<li><em>explications par Stéphane Bortzmeyer</em> : <a href="https://www.bortzmeyer.org/1305.html" rel="external">https://www.bortzmeyer.org/1305.html</a></li>
</ul>
</li>
<li>RFC 5905 : <a href="https://tools.ietf.org/html/rfc5905" rel="external">https://tools.ietf.org/html/rfc5905</a> ;
<ul>
<li><em>explications par Stéphane Bortzmeyer</em> : <a href="https://www.bortzmeyer.org/5905.html" rel="external">https://www.bortzmeyer.org/5905.html</a></li>
</ul>
</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Apprendre à gérer un serveur de temps sous OpenBSD]]></summary>
        <published>2020-01-19T16:30:48+02:00</published>
        <updated>2023-04-30T17:05:08+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a60df368-d3cd-1939-eb90-db2442d3ea3b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/pkg/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Gestion des paquets (outils pkg_*)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="pkg" scheme="http://doc.huc.fr.eu.org/fr/tags/pkg/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>OpenBSD fournit des outils bien pratiques pour gérer l&rsquo;installation, la
mise à jour, la suppression des paquets officiels :</p>
<h3 id="installer">Installer</h3>
<ul>
<li><a href="https://man.openbsd.org/pkg_add" rel="external">pkg_add(1)</a> : ajouter et mettre-à-jour
un logiciel ; utiliser l&rsquo;option <code>-u</code> pour mettre à jour.</li>
</ul>
<h3 id="supprimer">Supprimer</h3>
<ul>
<li><a href="https://man.openbsd.org/pkg_delete.1" rel="external">pkg_delete(1)</a> : enlever un
logiciel</li>
</ul>
<h3 id="information">Information</h3>
<ul>
<li><a href="https://man.openbsd.org/pkg_info.1" rel="external">pkg_info(1)</a> : obtenir les
informations relatives au logiciel désiré</li>
</ul>
<h3 id="etat">Etat</h3>
<ul>
<li><a href="https://man.openbsd.org/pkg_check.8" rel="external">pkg_check(8)</a> : vérifier
l&rsquo;installation d&rsquo;un logiciel</li>
</ul>
<h3 id="explications">Explications</h3>
<ul>
<li>Chercher un paquet : <code>pkg_info -Q nom_du_paquet</code></li>
<li>Installer un paquet : <code>pkg_add nom_du_paquet</code></li>
<li>Supprimer un paquet : <code>pkg_delete nom_du_paquet</code></li>
<li>Supprimer les dépendances inutiles : <code>pkg_delete -a</code></li>
<li>Réparer un système cassé et vérifier son état : <code>pkg_check</code></li>
</ul>
<p>Vous trouverez plus d&rsquo;informations sur la page
&ldquo;<a href="https://www.openbsd.org/faq/faq15.html" rel="external">Package Management</a>&rdquo; <em>(en)</em>
de la FAQ Officielle d&rsquo;OpenBSD…</p>
<h2 id="astuces">Astuces</h2>
<h3 id="derrière-un-proxy">Derrière un proxy</h3>
<p>Il faut définir la variable d&rsquo;environnement <code>http_proxy</code>.</p>
<p>Dans votre fichier <code>~/.profile</code>, insérez la ligne suivante :</p>
<p><code>export http_proxy=http://utilisateur_du_proxy:mot_de_passe@ip_du_proxy:port</code></p>
<h2 id="dépannage">Dépannage</h2>
<p>Retrouvez ci-dessous les erreurs courantes :</p>
<h3 id="partial-">partial-*</h3>
<p>Lors d&rsquo;une installation de paquet interrompue pour une raison ou une autre,
pkg_ retient le paquet avec le nom <code>partial-nom_du_paquet</code>.</p>
<p>Il vaut mieux les supprimer.</p>
<h3 id="pkg_check">pkg_check</h3>
<blockquote>
<p>Au secours, plus rien ne fonctionne comme je veux !!!</p>
</blockquote>
<p>Un petit coup de <code>pkg_check</code> et hop, votre OpenBSD revit !</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Des outils pour la gestion des paquets sous OpenBSD : pkg_*]]></summary>
        <published>2020-01-19T16:30:43+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:01cf8269-53a8-48ca-9933-ff7d29f11392</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sysupgrade/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Sysupgrade : mettre à niveau le système de base vers une nouvelle version ou un nouvel instantané, sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="sysupgrade" scheme="http://doc.huc.fr.eu.org/fr/tags/sysupgrade/" />
        <content type="html"><![CDATA[<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/sysupgrade/#man-8-sysupgrade">man 8 sysupgrade</a></li>
</ul>
<h3 id="man-8-sysupgrade">man 8 sysupgrade</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>sysupgrade</strong> [<strong>-fkn</strong>] [<strong>-r</strong> | <strong>-s</strong>] [<strong>installurl</strong>]</p>
<h4 id="description">Description</h4>
<p><strong>sysupgrade</strong> est un utilitaire pour mettre à niveau OpenBSD vers la
nouvelle version <em>(release)</em> ou un nouvel instantané <em>(snapshot)</em> si disponible.</p>
<p><strong>sysupgrade</strong> télécharge les fichiers nécessaires vers _<em>/home/<em>sysupgrade</em></em>,
les vérifie avec <a href="http://man.openbsd.org/signify" rel="external">signify(1)</a>, et copie
bsd.rd vers <strong>/bsd.upgrade</strong>.</p>
<p><strong>sysupgrade</strong> redémarre par défaut le système. Le chargeur de démarrage
choisira automatiquement <strong>/bsd.upgrade</strong>, déclenchant une mise à niveau
en une seule fois utilisant les fichiers déposés dans _<em>/home/<em>sysupgrade</em></em>.</p>
<p>Les options sont les suivantes :</p>
<ul>
<li><strong>-f</strong> : force une mise à niveau déjà appliquée. Par défaut, elle met
à niveau seulement le dernier instantané s&rsquo;il est disponible. Cette
option n&rsquo;a pas d&rsquo;effet sur une nouvelle version.</li>
<li><strong>-k</strong> : Garde les fichiers dans _<em>/home/<em>sysupgrade</em></em>. Par défaut,
ils seront supprimés après la mise à niveau.</li>
<li><strong>-n</strong> : Récupère et vérifie les fichiers et crée le fichier <strong>/bsd.upgrade</strong>
mais ne redémarre pas.</li>
<li><strong>-r</strong> : Mise à niveau vers la nouvelle version. Si le système fonctionne
actuellement sur une release, elle est active par défaut.</li>
<li><strong>-s</strong> : Mise à niveau vers un instantané. Si le système fonctionne
actuellement sur un instantané, elle est active par défaut.</li>
</ul>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><strong>/auto_upgrade.conf</strong> : fichier de réponse pour le noyau ramdisk.</li>
<li><strong>/bsd.upgrade</strong> : le noyau qui déclenche la mise à niveau sans surveillance.</li>
<li><strong>/etc/installurl</strong> : URL du miroir d&rsquo;OpenBSD pour récupérer la mise à niveau.</li>
<li>_<em>/home/<em>sysupgrade</em></em> : répertoire où la mise à niveau est téléchargée</li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="https://man.openbsd.org/signify" rel="external">signify(1)</a>, <a href="https://man.openbsd.org/installurl.5" rel="external">installurl(5)</a>, <a href="http://man.openbsd.org/autoinstall.8" rel="external">autoinstall(8)</a>, <a href="https://man.openbsd.org/release.8" rel="external">release(8)</a></li>
</ul>
<h4 id="histoire">Histoire</h4>
<p><strong>sysupgrade</strong> est apparu la première fois dans OpenBSD 6.6</p>
<hr>
<p><em>Traduction du manpage <a href="http://man.openbsd.org/sysupgrade" rel="external">sysupgrade(8)</a> !</em></p>
<hr>
<h3 id="informations-supplémentaires">Informations supplémentaires</h3>
<p>À-partir d&rsquo;OpenBSD 6.7, <code>sysupgrade</code> invoque l&rsquo;outil
<a href="https://man.openbsd.org/fw_update" rel="external">fw_update(1)</a>. <em>(cf : <a href="https://www.openbsd.org/67.html" rel="external">6.7</a>)</em> :</p>
<blockquote>Added an opportunistic run of fw_update(1) to sysupgrade(8) before rebooting to run the upgrade. </blockquote>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Upgrader de version sous OpenBSD, grâce à l&#39;outil &#39;sysupgrade&#39;.]]></summary>
        <published>2020-01-19T16:30:29+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b769a3ee-b5b2-b8a9-71ed-914362bb15b8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/installurl/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: installurl : localisation du serveur miroir OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="installurl" scheme="http://doc.huc.fr.eu.org/fr/tags/installurl/" />
        <content type="html"><![CDATA[<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/installurl/#man-5-installurl">man 5 installurl</a></li>
</ul>
<h3 id="man-5-installurl">man 5 installurl</h3>
<h4 id="description">Description</h4>
<p>Le fichier <code>/etc/installurl</code> contient une simple ligne spécifiant un serveur
miroir d&rsquo;OpenBSD, tel que :</p>
<p><code>https://ftp.openbsd.org/pub/OpenBSD</code></p>
<p>Il est créé par le script d&rsquo;installation durant les phases d&rsquo;installation
et de mises à niveau par le biais d&rsquo;HTTP.</p>
<p>Les lignes vides et les lignes commençant par le symbole &lsquo;#&rsquo; dans le fichier
sont ignorées.</p>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><code>/etc/installurl</code></li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="https://man.openbsd.org/pkg_add.1" rel="external">pkg_add(1)</a>, <a href="https://man.openbsd.org/syspatch.8" rel="external">syspatch(8)</a>, <a href="https://man.openbsd.org/sysupgrade.8" rel="external">sysupgrade(8)</a></li>
</ul>
<hr>
<p><em>Traduction du manpage <a href="https://man.openbsd.org/installurl.5" rel="external">installurl(5)</a> !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installurl - un procédé très simple pour localiser un miroir OpenBSD]]></summary>
        <published>2020-01-19T16:30:27+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:962925db-df18-51eb-e07a-66a141475584</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tutoriel-pandoc/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Installer et utiliser Pandoc / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="cabal" scheme="http://doc.huc.fr.eu.org/fr/tags/cabal/" />
        <category term="pandoc" scheme="http://doc.huc.fr.eu.org/fr/tags/pandoc/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Pandoc n&rsquo;est pas empaqueté sous OpenBSD. On peut quand même l&rsquo;installer,
mais il faut passer par le biais de l&rsquo;outil
<a class="inside" href="/fr/sys/openbsd/cabal/" title="Lien interne vers l&#39;article : 'Installer l&#39;outil Cabal sous OpenBSD'">cabal</a>
 !</p>
<h2 id="pré-requis">Pré-requis</h2>
<p>Modifiez le fichier <code>/etc/login.conf</code> pour avoir la ligne suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">:datasize-cur</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">infinity:\</span>
</span></span></code></pre></div><p>Dans la section &ldquo;default&rdquo; si vous voulez le permettre pour tous les
utilisateurs, sinon pour seulement la section &ldquo;staff&rdquo;.</p>
<h2 id="installation">Installation</h2>
<p>En plus, d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

l&rsquo;outil <code>cabal-install</code>, il semble nécessaire d&rsquo;installer aussi le
paquet <code>ghc</code>.</p>
<p>Deuxièmement, il importe de faire les
<a class="inside" href="/fr/sys/openbsd/cabal/#modifications-syst%c3%a8me" title="Lien interne vers l&#39;article : 'Installer l&#39;outil Cabal sous OpenBSD'">modifications systèmes</a>

nécessaires pour l&rsquo;usage correct de <code>cabal</code>.</p>
<p>Ensuite, utilisez <code>cabal</code> de manière à installer <code>pandoc</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cabal new-update
</span></span><span style="display:flex;"><span>$ cabal new-install pandoc
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<h3 id="does-not-exist-no-such-file-or-directory">does not exist (No such file or directory)</h3>
<p>Si une erreur de ce type apparaît:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>ghc-pkg: /home/hvr/.cabal/store/ghc-8.6.6/package.db: getDirectoryContents:openDirStream: does not exist <span style="color:#5bc4bf">(</span>No such file or directory<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p><strong>Créez les dossiers manquants avant l&rsquo;installation</strong> de pandoc:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mkdir -p <span style="color:#ef6155">$HOME</span>/.cabal/store/ghc-8.6.4/
</span></span><span style="display:flex;"><span>ghc-pkg init <span style="color:#ef6155">$HOME</span>/.cabal/store/ghc-8.6.4/package.db
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mini-tutoriel pour utiliser pandoc sous OpenBSD]]></summary>
        <published>2020-01-19T15:08:49+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:af3bc57f-33ba-c75a-05ec-1723b149d321</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/hotplugd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: hotplug-diskmount : utiliser un périphérique USB facilement / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="hotplugd" scheme="http://doc.huc.fr.eu.org/fr/tags/hotplugd/" />
        <category term="fuse" scheme="http://doc.huc.fr.eu.org/fr/tags/fuse/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.bsdua.org/hotplug-diskmount.html" rel="external">hotplug-diskmount</a></strong> est
un plugin pour le <a href="http://man.openbsd.org/hotplugd.8" rel="external"><code>hotplugd(8)</code></a>
d&rsquo;OpenBSD qui monte automatiquement les périphériques à chaud.
Il fonctionne avec tout type de disque <em>(des périphériques de stockage de
masse USB, des lecteurs de cartes, et CD/DVD)</em> et il est prévu pour être
utilisé dans des environnements d&rsquo;utilisateur uniques tels que des
ordinateurs de bureau ou des portables.</p>
<ul>
<li>La page du projet : <a href="http://www.bsdua.org/hotplug-diskmount.html" rel="external">http://www.bsdua.org/hotplug-diskmount.html</a></li>
<li>Le dépôt des sources : <a href="https://bitbucket.org/alex_vatchenko/hotplug-diskmount" rel="external">https://bitbucket.org/alex_vatchenko/hotplug-diskmount</a></li>
</ul>
<h3 id="informations">Informations</h3>
<p><strong>hotplug-diskmount</strong> semble se baser sur la détection des informations
qui sont retournées par disklabel, aussi !</p>
<p><strong>hotplug-diskmount</strong> gère les partitions de type :</p>
<ul>
<li><strong>Fat, FAT32</strong> (msdos) (lecture/écriture),</li>
<li><strong>NTFS</strong> (lecture/écriture) - L&rsquo;écriture est possible grâce à Fuse -
<em>veillez à l&rsquo;avoir installer auparavant !</em> - support ajouté avec la
version 1.0.2</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong>, il semble exister un bogue de détection ; en effet, si la
table de partition de votre périphérique USB est de type &ldquo;(ms)dos&rdquo;, le
périphérique sera détecté et monté correctement ; si la table de partition
est de type &ldquo;GPT&rdquo;, cela ne sera pas le cas. Pour l&rsquo;instant, avec la
version 1.0.2, veillez à ce que votre table de partition soit &ldquo;(ms)dos&rdquo; !</div>

<ul>
<li><strong>iso 9660</strong> - non testé</li>
<li><strong>ext2/3</strong> (lecture/écriture) - monte effectivement :
<ul>
<li>thunar plante ;</li>
<li>fonctionne sans soucis avec &lsquo;mc&rsquo; en mode console&rsquo;.</li>
</ul>
</li>
<li><strong>ext4</strong> (lecture) - cherche à le monter, mais se vautre. Il semble
<em>nécessaire de faire le point de montage à la main</em>, avec les droits
administrateur.</li>
</ul>
<h4 id="openbsd--61">OpenBSD ≥ 6.1</h4>
<p>Depuis la version 6.1, OpenBSD utilise la version 1.0.2 du projet !</p>
<h4 id="openbsd--60">OpenBSD ≤ 6.0</h4>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<p><strong>Veuillez à mettre-à-niveau</strong> !</p>
<p>OpenBSD 6.0 utilise la version 0.9 - <em>elle est clairement dépassée, et
peut ne pas fonctionner sur certains périphériques ; la raison est que
depuis février 2015, date de sortie de la v0.9, la structure du
fonctionnement de l&rsquo;outil
&lsquo;<a href="http://man.openbsd.org/OpenBSD-current/man8/disklabel.8" rel="external">disklabel(8)</a>&rsquo;
a été modifiée. Dans ce contexte, il serait plus intéressant d&rsquo;utiliser
la version de l&rsquo;arbre des ports, à ce jour la v1.0.</em></p>
<p>Néanmoins, il vaut mieux utiliser la version 1.0.2, car celle-ci ajoute
le support ntfs grâce à l&rsquo;ajout de la gestion du projet
<a href="http://man.openbsd.org/OpenBSD-current/man4/fuse.4" rel="external">fuse(4)</a>.</p>
<h2 id="installation">Installation</h2>
<h3 id="pré-requis">Pré-requis</h3>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>fuse</code></strong>.</p>
<h3 id="openbsd--61-1">OpenBSD ≥ 6.1</h3>
<p>Il suffit d&rsquo;<strong>[[system:base:pkg|installer]] le paquet <code>hotplug-diskmount</code></strong>.</p>
<h3 id="openbsd--60-1">OpenBSD ≤ 6.0</h3>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<p><strong>Veuillez à mettre-à-jour</strong> !</p>
<h3 id="initialisation">Initialisation</h3>
<p>Il est IMPORTANT d&rsquo;initialiser le projet pour créer son répertoire de
montage par défaut - normalement <code>/vol</code> :</p>
<p><code># /usr/local/libexec/hotplug-diskmount init</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Il est intéressant à noter que l&rsquo;on peut spécifier un répertoire cible
en utilisant l&rsquo;option <code>-d</code>, tel que :</p>
<p><code># /usr/local/libexec/hotplug-diskmount -d /mnt/$USER init</code></p>
</div>

<p>Il est ensuite nécessaire d&rsquo;
<a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">activer le service</a>

<code>hotplugd</code>…</p>
<h2 id="configuration">Configuration</h2>
<p>Il faut créer/modifier le fichier <code>/etc/hotplug/attach</code> :</p>
<p><code># nano /etc/hotplug/attach</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">DEVCLASS</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">1</span><span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">DEVNAME</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">2</span><span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">LOGIN</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;votre_id_user&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">DEVCLASS</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        2<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>        /usr/local/libexec/hotplug-diskmount attach -u <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">LOGIN</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -m <span style="color:#f99b15">0700</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">DEVNAME</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">esac</span>
</span></span></code></pre></div><p>puis veillez à ce qu&rsquo;il soit exécutable :</p>
<p><code># chmod +x /etc/hotplug/attach</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>Note</strong> : Modifier la valeur de la variable LOGIN, en ligne 5, avec
votre identifiant de session utilisateur. De même, il est spécifié le
mode &lsquo;0700&rsquo; afin que nul autre n&rsquo;ait accès au contenu !</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Toute modification dans ce fichier nécessitera le
redémarrage du démon hotplugd !</p>
<p><em>Autrement, celles-ci ne seront pas prises en compte.</em></p>
</div>

<h2 id="démarrage">Démarrage</h2>
<p><a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Démarrez le service</a>

<code>hotplugd</code> afin que les modifications soient gérées  !</p>
<h2 id="vérification">Vérification</h2>
<p>Après avoir inséré votre périphérique USB, ou CD-Rom…</p>
<p>En mode console :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ mount 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>/dev/sd1i on /vol/DataTraveler 3. type msdos <span style="color:#5bc4bf">(</span>local, nodev, nosuid, <span style="color:#ef6155">uid</span><span style="color:#5bc4bf">=</span>1000, <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">mask</span><span style="color:#5bc4bf">=</span>0700<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ ls -al /vol/                                                                                                                             
</span></span><span style="display:flex;"><span>total <span style="color:#f99b15">44</span>
</span></span><span style="display:flex;"><span>drwxr-xr-x   <span style="color:#f99b15">4</span> root  wheel    <span style="color:#f99b15">512</span> Sep <span style="color:#f99b15">15</span> 22:50 .
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">15</span> root  wheel    <span style="color:#f99b15">512</span> Sep <span style="color:#f99b15">12</span> 23:04 ..
</span></span><span style="display:flex;"><span>drwx------   <span style="color:#f99b15">2</span> root  wheel    <span style="color:#f99b15">512</span> Sep <span style="color:#f99b15">15</span> 22:50 .db
</span></span><span style="display:flex;"><span>drwx------   <span style="color:#f99b15">1</span> votre_id_user   wheel  <span style="color:#f99b15">16384</span> Jan  <span style="color:#f99b15">1</span>  <span style="color:#f99b15">1980</span> DataTraveler 3.
</span></span></code></pre></div><p>En mode graphique, utilisez donc votre navigateur de fichiers,
dirigez-vous vers le volume <code>/vol</code> - <em>ou le répertoire cible que vous
auriez précisé</em> - où vous trouverez un répertoire créé automatiquement
selon le label correspondant à votre périphérique.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le fichier <code>/usr/local/share/doc/pkg-readmes/hotplug-diskmount</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser un périphérique USB sous OpenBSD grâce au projet &#39;hotplugd&#39;.]]></summary>
        <published>2020-01-19T15:03:34+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c7487cfc-dbb2-f367-9ef9-24ee9076135a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/consolekit/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Consolekit2 (bus de messages) / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="consolekit" scheme="http://doc.huc.fr.eu.org/fr/tags/consolekit/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://github.com/ConsoleKit2/ConsoleKit2" rel="external">ConsoleKit2</a></strong> est un
framework permettant de définir et de suivre les utilisateurs, les
sessions de connexion et les seats. Il permet à de multiples utilisateurs
d&rsquo;être connectés en même temps et de partager le matériel pour leur
session graphique. ConsoleKit2 gardera une trace de ces ressources et,
quelle que soit la session active, utilisera le matériel à ce moment-là.</p>
<h3 id="définition-dun-seat">Définition d&rsquo;un seat</h3>
<p>Un seat est une collection de sessions et de paramètres matériels
(habituellement au moins un clavier et une souris). Une seule session
peut être active à la fois par seat.</p>
<h3 id="définition-dune-session">Définition d&rsquo;une session</h3>
<p>Une session est une collection de tous les processus qui proviennent
d&rsquo;un seul ancêtre commun et qui conservent la connaissance d&rsquo;un secret.
En tant que détail d&rsquo;implémentation, ce secret peut être enregistré dans
un processus d&rsquo;environnement par le gestionnaire de session sous le nom
de <code>XDG_SESSION_COOKIE</code>.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 les
paquets <code>consolekit2 polkit</code></strong>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Certains packages l&rsquo;installent automatiquement en tant que dépendance
requise…</div>

<h2 id="configuration">Configuration</h2>
<p>Pour activer <code>consolekit</code> dans une session graphique, il est nécessaire
de préfixer le binaire <code>ck-launch-session</code> dans le script de session,
tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/usr/local/bin/ck-launch-session /usr/local/bin/openbox-session
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Le gestionnaire de session <code>gdm</code> s&rsquo;occupe automatiquement de cette
fonction</p>
<ul>
<li><strong>dans ce cas, il est important de ne rien modifier !</strong></li>
</ul></div>

<h3 id="démarrage-de-service-nécessaire">Démarrage de service nécessaire</h3>
<p>Il est nécessaire que le service <code>system-wide D-Bus</code> fonctionne en premier.</p>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer le service</a>
 <code>messagebus</code></li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#ordonner" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Ordonner le service</a>

en tout premier</li>
<li>puis <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Démarrer le service</a>
</li>
</ul>
<h3 id="log-history">Log <code>history</code></h3>
<p>Il peut être utile, du fait que le journal <code>history</code> puisse devenir gros,
de prévoir de faire une rotation de celui-ci.</p>
<p>Ouvrez, avec vos droits administrateurs, le fichier <code>/etc/newsyslog.conf</code>
et ajouter, par exemple, la ligne suivante :</p>
<p><code>/var/log/ConsoleKit/history     root:wheel      640     7       *       *       Z</code></p>
<p>Puis, relancez <code>newsyslog</code>…</p>
<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de lire le fichier
<code>/usr/local/share/doc/pkg-readmes/consolekit2</code> !</p>
<p>Vous pouvez aussi lire les exemples :</p>
<ul>
<li>dans <code>/usr/local/share/examples/consolekit/</code></li>
<li>et dans <code>/usr/local/share/examples/polkit/</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Consolekit2 est un utilitaire sous OpenBSD pour suivre les sessions]]></summary>
        <published>2020-01-19T14:52:56+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:6c7711d5-b3be-87f1-bc46-1ac2c3ea27a3</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tutoriel-mount-usb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Monter un disque / une clé USB en tant qu’utilisateur sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="USB" scheme="http://doc.huc.fr.eu.org/fr/tags/usb/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Sous OpenBSD, il existe différents moyens de monter un disque dur USB, ou
une clé USB…</p>
<h2 id="méthode-automatique">Méthode automatique</h2>
<h3 id="openbsd--60">OpenBSD ≥ 6.0</h3>
<p>À partir d&rsquo;OpenBSD 6.0 et supérieures, il semble préférable de se
diriger vers l&rsquo;usage du démon <code><a class="inside" href="/fr/sys/openbsd/hotplugd/" title="Lien interne vers l&#39;article : 'hotplug-diskmount : utiliser un périphérique USB facilement / OpenBSD'">hotplugd</a>
</code>
et du binaire &lsquo;hotplug-diskmount&rsquo;.</p>
<h3 id="openbsd--60-1">OpenBSD &lt; 6.0</h3>
<p>Il faut modifier l’option <code>kern.usermount</code>.</p>
<p><code># sysctl kern.usermount=1</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION : cette option n&rsquo;est plus disponible à partir d&rsquo;OpenBSD 6.0</strong></div>

<p>Par sécurité, ce paramétrage retrouve sa valeur par défaut au redémarrage.</p>
<p>Malgré tout, si vous souhaitez qu&rsquo;il soit pris en compte de façon
permanente, ajoutez ceci au fichier <code>/etc/sysctl.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">kern.usermount</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span></code></pre></div><hr>
<h2 id="méthode-manuelle">Méthode &ldquo;manuelle&rdquo;</h2>
<p><strong>Cette méthode est à recommander que si et seulement si les méthodes
automatiques ci-dessus ne fonctionnent pas, ou si vous préférez vous en
passer !</strong></p>
<ul>
<li><em>ce qui signifie que vous comprenez correctement les étapes décrites
ci-dessous !</em></li>
</ul>
<h3 id="identification-de-la-clé">Identification de la clé</h3>
<p>Tout d’abord, repérez le nom de votre clé USB avec la commande <code>dmesg</code>
juste après l&rsquo;avoir insérée :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>umass1 at uhub2 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;SanDisk Cruzer Edge&#34;</span> rev 2.00/1.27 addr <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>umass1: using SCSI over Bulk-Only scsibus5 at umass1: <span style="color:#f99b15">2</span> targets, initiator <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>sd2 at scsibus5 targ <span style="color:#f99b15">1</span> lun 0: &lt;SanDisk, Cruzer Edge, 1.27&gt; SCSI4 0/direct removable serial.0781556b42119B2141E2
</span></span><span style="display:flex;"><span>sd2: 15267MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">31266816</span> sectors
</span></span></code></pre></div><p>Ici, la clé est donc <code>sd2</code> !</p>
<p>Ensuite, avec la commande disklabel, vous pouvez repérer les partitions
contenues sur la clé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ disklabel sd2
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /dev/rsd2c:</span>
</span></span><span style="display:flex;"><span>type: SCSI
</span></span><span style="display:flex;"><span>disk: SCSI disk
</span></span><span style="display:flex;"><span>label: Cruzer Edge
</span></span><span style="display:flex;"><span>duid: <span style="color:#f99b15">0000000000000000</span>
</span></span><span style="display:flex;"><span>flags:
</span></span><span style="display:flex;"><span>bytes/sector: <span style="color:#f99b15">512</span>
</span></span><span style="display:flex;"><span>sectors/track: <span style="color:#f99b15">63</span>
</span></span><span style="display:flex;"><span>tracks/cylinder: <span style="color:#f99b15">255</span>
</span></span><span style="display:flex;"><span>sectors/cylinder: <span style="color:#f99b15">16065</span>
</span></span><span style="display:flex;"><span>cylinders: <span style="color:#f99b15">1946</span>
</span></span><span style="display:flex;"><span>total sectors: <span style="color:#f99b15">31266816</span>
</span></span><span style="display:flex;"><span>boundstart: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>boundend: <span style="color:#f99b15">31266816</span>
</span></span><span style="display:flex;"><span>drivedata: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">16</span> partitions:
</span></span><span style="display:flex;"><span><span style="color:#776e71">#                size           offset  fstype [fsize bsize  cpg]</span>
</span></span><span style="display:flex;"><span>  c:         <span style="color:#f99b15">31266816</span>                <span style="color:#f99b15">0</span>  unused
</span></span><span style="display:flex;"><span>  i:         <span style="color:#f99b15">31264768</span>             <span style="color:#f99b15">2048</span>   MSDOS
</span></span></code></pre></div><h3 id="montage-de-la-clé">Montage de la clé</h3>
<p>Enfin, il suffit de monter la clé dans un dossier qui vous appartient.
Ici, la partition intéressante est la <code>i</code>. Par exemple pour la monter
dans le dossier <code>~/usb</code> qui se trouve dans votre répertoire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># mount /dev/sd2i ~/usb</span>
</span></span></code></pre></div><h3 id="permission-de-lecture-et-décriture">Permission de lecture et d&rsquo;écriture</h3>
<p>Il reste un problème à régler. Si vous jetez un oeil aux droits d&rsquo;accès
de votre clé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ls -la /dev/sd2i
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>brw-r-----  <span style="color:#f99b15">1</span> root  operator    4,   <span style="color:#f99b15">24</span> Apr <span style="color:#f99b15">30</span> <span style="color:#f99b15">2016</span> 10:29    /dev/sd2i
</span></span></code></pre></div><p>Vous remarquez que seul root et les membres du groupe <code>operator</code> ont
les droits requis.</p>
<p>Ajout de votre utilisateur au groupe <code>operator</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usermod -G operator toto</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ groupinfo operator
</span></span><span style="display:flex;"><span>name    operator
</span></span><span style="display:flex;"><span>passwd  *
</span></span><span style="display:flex;"><span>gid     <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>members root toto
</span></span></code></pre></div><p>Donner au groupe <code>operator</code> les droits adéquats sur votre device, ici
<code>/dev/sd2</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># chmod g=rw /dev/sd2*</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION : Ces permissions sont à rétablir à chaque fois que vous
mettrez à jour votre système de base !!!</strong></div>

<h3 id="démontage-de-la-clé">Démontage de la clé</h3>
<p>Pour démonter un périphérique cela se réalise avec la commande
<a href="http://man.openbsd.org/man8/umount.8" rel="external"><code>umount</code>(8)</a>.</p>
<p>On peut soit démonter à partir du périphérique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># umount /dev/sd2i</span>
</span></span></code></pre></div><p>Soit à partir de son point de montage :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># umount ~/usb</span>
</span></span></code></pre></div><p>Si jamais on obtient une erreur concernant l&rsquo;utilisation du point de
montage (occupé), il faut vérifier que les divers terminaux / logiciels
n&rsquo;utilisent plus le répertoire en question.</p>
<p>La commande <a href="http://man.openbsd.org/man1/fstat.1" rel="external"><code>fstat</code>(1)</a> peut aider
pour voir rapidement quel logiciel y est attaché :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># umount ~/usb</span>
</span></span><span style="display:flex;"><span>umount: ~/usb: Device busy
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># fstat -f ~/usb/</span>
</span></span><span style="display:flex;"><span>USER     CMD          PID   FD MOUNT        INUM  MODE         R/W    SZ|DV
</span></span><span style="display:flex;"><span>toto     pcmanfm    <span style="color:#f99b15">21084</span>  <span style="color:#f99b15">114</span> ~/usb           <span style="color:#f99b15">4</span>  drwxr-xr-x     r    <span style="color:#f99b15">32768</span>
</span></span></code></pre></div><p>Dans l&rsquo;exemple ci-dessus on peut voir que pcmanfm occupe le point de
montage <code>~/usb</code>, ayant pour PID 21084.</p>
<p>On peut alors soit changer de répertoire à partir de pcmanfm, soit le
fermer, voire le tuer avec la commande <a href="http://man.openbsd.org/man1/kill.1" rel="external"><code>kill</code>(1)</a>.</p>
<p>C&rsquo;est ce dernier cas qu&rsquo;on va utiliser dans l&rsquo;exemple suivant.
On va tuer le processus de pcmanfm, vérifier à nouveau avec fstat pour
savoir si le point de montage est bien libre, puis démonter le
périphérique avec <code>umount</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># kill 21084</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># fstat -f ~/usb/</span>
</span></span><span style="display:flex;"><span>USER     CMD          PID   FD MOUNT        INUM  MODE         R/W    SZ|DV
</span></span><span style="display:flex;"><span><span style="color:#776e71"># umount –/usb</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mini-tutoriel pour monter un périphérique de mémoire de masse USB sous OpenBSD]]></summary>
        <published>2020-01-19T14:50:35+02:00</published>
        <updated>2025-10-06T11:59:02+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:65fc0f53-bbf9-e6e1-9096-11dfaef93a04</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/anacron/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: anacron : utiliser comme simple utilisateur / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="anacron" scheme="http://doc.huc.fr.eu.org/fr/tags/anacron/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Anacron</strong> est un ordonnanceur de commandes périodiques. Il exécute des
commandes à intervalles spécifiées par jours. À la différence de cron,
il n&rsquo;a pas besoin que le système fonctionne en continue. Il peut
toutefois être utilisé pour contrôler l&rsquo;exécution de travaux quotidiens,
hebdomadaires et mensuels (ou toute autre période de n jours), sur des
systèmes qui ne fonctionnent pas 24 heures par jour. Quand il est installé
et configuré proprement, Anacron s&rsquo;assurera que les commandes soient
exécutées aux intervalles spécifiées aussi précisément que le permet la
disponibilité de la machine.</p>
<p>Ce que ne fait pas Anacron : Anacron n’essaie pas de faire un cron
redondant. Il ne peut être utilisé pour programmer des commandes à des
intervalles plus petites que la journée. Il ne garantit pas que les
commandes seront exécutées à heure ou jour spécifique. Ce n&rsquo;est pas un
démon à plein temps. Il est exécuté depuis des scripts de démarrage, des
travaux cron, ou explicitement.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>anacron</code></strong>.</p>
<p>Ce dernier est souvent utilisé en tant qu&rsquo;administrateur. On rajoute dans
ce cas les tâches à effectuer dans le fichier <code>/etc/anacrontab</code> puis on
le lance à chaque démarrage avec une nouvelle entrée dans <code>/etc/rc.local</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/usr/local/sbin/anacron -ds
</span></span></code></pre></div><p>Ce n&rsquo;est pas très intéressant sur une machine de bureau où l&rsquo;on peut
vouloir lancer des commandes spécifiques aux utilisateurs (pour utiliser
les clés ssh par exemple).</p>
<h2 id="configuration">Configuration</h2>
<p>On crée le fichier <code>~/.anacron/anacrontab</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ mkdir -p ~/.anacron/
</span></span><span style="display:flex;"><span>$ vi ~/.anacron/anacrontab
</span></span></code></pre></div><p>On écrit dans ce fichier sur chaque ligne les tâches à lancer régulièrement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># period  delay  job-identifier  command</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sauvegarde des cours</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># &lt;Tous les n jours&gt; &lt;séparé de 10 minutes avec les autres tâches&gt; &lt;nom de la tâche&gt; &lt;commande à lancer&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">1   10  educ /home/xavier/geek/bin/sauvegarde/synccours</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sauvegarde des documents</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">7   10  backup /home/xavier/geek/bin/sauvegarde/backup_home</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sauvegarde du serveur web</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">7   10  webbackup /home/xavier/geek/bin/sauvegarde/savewww</span>
</span></span></code></pre></div><p>Notez qu&rsquo;inscrire <code>1</code> en premier revient à écrire <code>@daily</code> pour lancer
la commande chaque jour, et <code>7</code> à <code>@weekly</code> pour la lancer de façon
hebdomadaire.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong> : Les commandes doivent être précisées avec leur chemins
complets.</div>

<p>Afin d&rsquo;avoir les droits de lancer anacron en tant qu&rsquo;utilisateur et
écrire dans la file d&rsquo;attente, on peut s&rsquo;ajouter dans le groupe <code>wheel</code>.
Il existe peut-être une meilleure solution, comme définir un emplacement
de file d&rsquo;attente différent que celui par défaut, mais je ne l&rsquo;ai pas
encore trouvé.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usermod -G wheel jdoe</span>
</span></span></code></pre></div><p>On donne les droits pour le groupe wheel d&rsquo;écrire dans la liste d&rsquo;attente :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># chmod g+xrw /var/spool/anacron</span>
</span></span></code></pre></div><p>Enfin, pour lancer anacron à chaque démarrage, on peut mettre dans le
fichier <code>~.profile</code> ceci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/sbin/anacron -s -t ~/.anacron/anacrontab</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser l&#39;ordonnanceur anacron pour gérer des tâches périodiques sous OpenBSD]]></summary>
        <published>2020-01-19T14:35:54+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:07b3379e-85b4-751c-4f21-8a4ef3290336</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/pycharm/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PyCharm [ Python IDE ]</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <category term="Pycharm" scheme="http://doc.huc.fr.eu.org/fr/tags/pycharm/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>L&rsquo;IDE PyCharm fournit une complétion de code intelligente, l&rsquo;inspection
du code, le surlignement des erreurs à la volée, des correctifs rapides,
des modifications automatiques du code et offre des fonctionnalités
avancées de navigation.</p>
<ul>
<li>Architectures gérées : toutes ?</li>
<li>Mainteneur : Rafael Sadowski</li>
<li>Openports : <a href="https://openports.pl/path/devel/pycharm" rel="external">https://openports.pl/path/devel/pycharm</a></li>
<li>Site web officiel : <a href="https://download.jetbrains.com/python/" rel="external">https://download.jetbrains.com/python/</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>pycham</code></strong>.</p>
<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de <strong>lire le fichier  <code>/usr/local/share/doc/pkg-readmes/pycharm</code></strong> ! ;-)</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="bad-limit">Bad limit</h3>
<p>Au lancement, vous avez la fenêtre d&rsquo;erreur <code>xmessage</code> :</p>
<blockquote>Cannot increase datasize-cur to a least 2048000. <br>
Do you want to run PyCharm anyway? <br>
(If you don't increase this limits, PyCharm may fail to work properly).
</blockquote>
<p>De même, si vous l&rsquo;exécutez en mode console, vous avez le message suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ pycharm                                                                                                                              
</span></span><span style="display:flex;"><span>/usr/local/bin/pycharm<span style="color:#5bc4bf">[</span>41<span style="color:#5bc4bf">]</span>: ulimit: bad -d limit: Invalid argument
</span></span><span style="display:flex;"><span>egrep: -: No such file or directory
</span></span><span style="display:flex;"><span>Error occurred during initialization of VM
</span></span><span style="display:flex;"><span>Could not reserve enough space <span style="color:#815ba4">for</span> 768000KB object heap
</span></span></code></pre></div><p>Il est nécessaire de modifier la limite système <code>datasize-cur</code> à une
valeur minimale de <code>2G</code>.</p>
<p>Redémarrez votre session, avant de chercher à utiliser PyCharm !</p>
<h3 id="problèmes-de-fenêtrage">Problèmes de fenêtrage</h3>
<p>Si l’écran d’accueil s’affiche mais que vous ne voyez alors qu’un écran
principal gris, <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez le package</a>

<code>wmname</code> et exécutez :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>wmname LG3D
</span></span></code></pre></div><p>C&rsquo;est un problème vu avec certaines applications basées sur Java utilisées
avec un gestionnaire de fenêtre non réparateur (tel que
<a class="inside" href="/fr/sys/openbsd/cwm/" title="Lien interne vers l&#39;article : 'cwm (gestionnaire de fenêtres) / OpenBSD'">cwm (gestionnaire de fenêtres) / OpenBSD</a>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser l&#39;IDE Pycharm sous OpenBSD]]></summary>
        <published>2020-01-19T14:30:00+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:325c240b-9fed-3bd5-8e84-474b9a9c9536</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tor/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Tor : service d&#39;anonymat par onion routage / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Tor" scheme="http://doc.huc.fr.eu.org/fr/tags/tor/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Tor</strong> est un système de communication anonyme à latence basse qui
protège les flux TCP : navigation web, messagerie instantanée, irc, ssh,
etc…</p>
<p><em>Ne pas confondre avec le logiciel <a class="inside" href="/fr/sys/openbsd/tor-browser/" title="Lien interne vers l&#39;article : 'Tor Browser / OpenBSD'">Tor Browser / OpenBSD</a> !</em></p>
<hr>
<ul>
<li>Architectures gérées :</li>
<li>Mainteneur : Pascal Stumpf</li>
<li>Openports : <a href="https://openports.pl/path/net/tor" rel="external">https://openports.pl/path/net/tor</a></li>
<li>Site officiel : <a href="https://www.torproject.org/" rel="external">https://www.torproject.org/</a></li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>tor</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="modifications-système">Modifications système</h3>
<p>Par défaut, OpenBSD maintient une limite basse de fichiers ouverts en
même temps. Le service <code>tor</code> a besoin pour fonctionner correctement
qu&rsquo;elles soient augmentées.</p>
<h4 id="fichier-etcloginconf">Fichier <code>/etc/login.conf</code></h4>
<p>Ajoutez ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">tor:\</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">:openfiles-max</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">13500:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    :tc=daemon:</span>
</span></span></code></pre></div><h4 id="sysctl-kernmaxfiles">sysctl <code>kern.maxfiles</code></h4>
<p>Il semble nécessaire d&rsquo;augmenter la limite des descripteurs de fichiers
gérés par le noyau :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># echo &#34;kern.maxfiles=16000&#34; &gt;&gt; /etc/sysctl.conf</span>
</span></span><span style="display:flex;"><span>$ sysctl kern.maxfiles<span style="color:#5bc4bf">=</span><span style="color:#f99b15">16000</span>
</span></span></code></pre></div><h2 id="utilisation">Utilisation</h2>
<h3 id="cli">CLI</h3>
<p>Pour utiliser un logiciel réseau avec tor, après avoir
<a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">activer</a>
 et
<a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrer</a>
 le service,
utilisez le binaire <code>torsocks</code> tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>torsocks -s 127.0.0.1 -P <span style="color:#f99b15">9050</span> nom-binaire
</span></span></code></pre></div><h3 id="gui">GUI</h3>
<p>Pour un logiciel graphique, tel Firefox, allez dans les paramètres de
préférences réseaux, puis configurez le proxy socks en choisissant, si
possible :</p>
<p>⇒ menu Édition &gt; Paramètres</p>
<ul>
<li>onglet &lsquo;Général&rsquo; &gt; Section &lsquo;Paramètres réseaux&rsquo;</li>
<li>bouton [ Paramètres ]</li>
</ul>
<p>⇒ puis, dans la fenêtre &lsquo;Paramètre de connexion&rsquo;, choisir :</p>
<ul>
<li>&lsquo;Configuration manuelle du proxy&rsquo;</li>
<li>champ &lsquo;Hôte&rsquo; : remplir <code>127.0.0.1</code></li>
<li>cliquer sur la case à cocher [ ] &lsquo;SOCKS v5&rsquo;</li>
<li>champ &lsquo;Port&rsquo; : remplir <code>9050</code> — <em>normalement est le port par défaut de
connexion établie par Tor</em></li>
</ul>
<hr>
<p>Voir la capture écran ci-jointe :
<figure>
    <a href="/images/openbsd/firefox-parametres-reseau-proxy.png" title="Paramètres réseau Proxy pour Firefox : menu Édition &gt; Paramètres ; onglet &#39;Général&#39; &gt; Paramètres réseaux ; bouton [ Paramètres ], puis choix de &#39;Configuration manuelle du proxy&#39; &gt; &#39;Hôte Socks&#39;, remplir : &#39;127.0.0.1&#39;, puis &#39;Port&#39;, remplir : &#39;9050&#39; ; validez par appui/click sur le bouton [ OK ]">
    <picture>
        
        <source srcset="/images/openbsd/firefox-parametres-reseau-proxy_hu_c88f2843644a523d.webp" type="image/webp">
        
        <img alt="Paramètres réseau Proxy pour Firefox : menu Édition &gt; Paramètres ; onglet &#39;Général&#39; &gt; Paramètres réseaux ; bouton [ Paramètres ], puis choix de &#39;Configuration manuelle du proxy&#39; &gt; &#39;Hôte Socks&#39;, remplir : &#39;127.0.0.1&#39;, puis &#39;Port&#39;, remplir : &#39;9050&#39; ; validez par appui/click sur le bouton [ OK ]" height="271" loading="lazy" src="/images/openbsd/firefox-parametres-reseau-proxy_hu_f901b60f22bd2dd.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Paramètres réseau Proxy pour Firefox : menu Édition > Paramètres ; onglet 'Général' > Paramètres réseaux ; bouton [ Paramètres ], puis choix de 'Configuration manuelle du proxy' > 'Hôte Socks', remplir : '127.0.0.1', puis 'Port', remplir : '9050' ; validez par appui/click sur le bouton [ OK ]</figcaption>
</figure></p>
<h2 id="documentation">Documentation</h2>
<p>Tutoriel complémentaire : <a href="https://community.torproject.org/relay/setup/guard/openbsd/" rel="external">https://community.torproject.org/relay/setup/guard/openbsd/</a></p>
<hr>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>Merci à JDG pour ses petites explications sur l&rsquo;utilisation de tor…</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le service d&#39;anonymat Tor sous OpenBSD]]></summary>
        <published>2020-01-19T14:24:39+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f1bc3683-b615-01c6-d796-9ba071261a56</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/jdk/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenJDK SDK, Standard Edition</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="JDK" scheme="http://doc.huc.fr.eu.org/fr/tags/jdk/" />
        <category term="JRE" scheme="http://doc.huc.fr.eu.org/fr/tags/jre/" />
        <category term="Java" scheme="http://doc.huc.fr.eu.org/fr/tags/java/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le logiciel OpenJDK inclut des outils utiles pour le développement et les
tests de programmes écrits dans le langage de programmation Java et
s&rsquo;exécutant dans une plate-forme Java.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>jdk</code></strong>.</p>
<ul>
<li>Version : 1.8.0</li>
<li>ou, version : 11-5</li>
</ul>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/jdk</code></li>
<li>ou pour <code>jdk-11*</code> : <code>/usr/local/share/doc/pkg-readmes/jdk-11</code></li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="variable-path">Variable PATH</h3>
<p>Pensez à modifier votre variable d&rsquo;environnement <code>PATH</code>, généralement
depuis votre fichier personnel <code>~/.profile</code>, pour y ajouter :</p>
<ul>
<li>pour jdk 1.8.0.* : <code>:/usr/local/jre-1.8.0/bin</code></li>
<li>pour jdk 11.5* : <code>:/ur/local/jdk-11/bin/</code></li>
</ul>
<p>Puis redémarrez votre session !</p>
<h3 id="gestion-de-la-mémoire">Gestion de la mémoire</h3>
<p>Par défaut, l&rsquo;empreinte de la mémoire est réduite à un usage de 256 Mo.
Pour les applications nécessitant plus de mémoire, utilisez l&rsquo;argument
<code>-XX:CompressedClassSpaceSize</code> et augmentez en conséquence, selon le besoin.</p>
<h3 id="réseau-ipv4-ipv6">Réseau IPv4, IPv6</h3>
<p>Le mappage d&rsquo;adresses IPv4 et IPv6 est désactivé. La conséquence est que
jdk utilisera soit les adresses IPv4, soit celles d&rsquo;IPv6, mais pas les
deux en même temps. La gestion de l&rsquo;adressage IPv4 est activée par défaut.
Pour activer IPv6, il vous faut paramétrer les propriétés suivantes au
moment de démarrer Java :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>  <span style="color:#06b6ef">-Djava.net.preferIPv4Stack</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">false
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  -Djava.net.preferIPv6Stack=true
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  -Djava.net.preferIPv6Addresses=true</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser OpenJDK, JRE, sous OpenBSD]]></summary>
        <published>2020-01-19T14:18:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:caee76c1-0678-a979-6433-2212bb708aa9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-unicode/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion de l&#39;Unicode sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="unicode" scheme="http://doc.huc.fr.eu.org/fr/tags/unicode/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>OpenBSD est UTF-8 !</p>
<h2 id="unicode">Unicode</h2>
<p>Néanmoins, votre clavier quelque soit la langue n&rsquo;est pas forcément
capable de gérer tous les codes Unicode en appuyant simplement sur une
seule touche.</p>
<p>Pour pouvoir générer un code Unicode, c&rsquo;est la combinaison des touches
<kbd>CTRL+Shift+u</kbd> suivi du code relatif au caractère à imprimer,
appelé code Unicode.</p>
<h2 id="exemples">Exemples</h2>
<ul>
<li>
<p>tiret &ldquo;demi-cadratin&rdquo; :
combinaison <kbd>CTRL+Shift+u</kbd> + <kbd>2+0+1+3</kbd> : <code>–</code></p>
</li>
<li>
<p>tiret &ldquo;cadratin&rdquo; : <kbd>CTRL+Shift+u</kbd> + <kbd>2+0+1+4</kbd> : <code>—</code></p>
</li>
<li>
<p>caractère <code>✓</code> : <kbd>CTRL+Shift+u</kbd> + <kbd>2+7+1+3</kbd></p>
</li>
<li>
<p>un espace insécable : <code> </code> : <kbd>CTRL+Shift+u</kbd> + <kbd>0+0+A+0</kbd></p>
</li>
<li>
<p>l&rsquo;arobase <code>@</code> : <kbd>CTRL+Shift+u</kbd> + <kbd>0+0+4+0</kbd></p>
</li>
<li>
<p>etc… <em>oui, les trois points de suspension suivant <code>etc</code> sont un
seul et même caractère unicode :</em>
<kbd>CTRL+Shift+u</kbd> + <kbd>2+0+2+6</kbd></p>
</li>
</ul>
<hr>
<h2 id="astuce">Astuce</h2>
<p>L&rsquo;unicode peut être géré par le biais de la touche de
<a class="inside" href="/fr/sys/openbsd/tip-compose/" title="Lien interne vers l&#39;article : 'Gestion de la touche de composition sous OpenBSD'">composition</a>
…</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Table de caractères Unicode : <a href="https://unicode-table.com/fr/" rel="external">https://unicode-table.com/fr/</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour gérer l&#39;unicode sous OpenBSD]]></summary>
        <published>2020-01-19T14:03:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d3d89a86-3af5-950d-9cf6-d51cbb26c123</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/cups/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Cups : Gestion de l&#39;impression sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="cups" scheme="http://doc.huc.fr.eu.org/fr/tags/cups/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.cups.org/" rel="external">CUPS</a></strong> fournit un calque d&rsquo;impression portable
pour les systèmes d&rsquo;exploitation basés sur UNIX. CUPS fournit des
interfaces en ligne de commande de System V et Berkeley.</p>
<p>CUPS utilise <abbr title="Internet Print Protocol">IPP</abbr>

(<em>Protocole d&rsquo;Impression Internet</em>) comme bases pour gérer
les queues et travaux d&rsquo;impressions. Les protocoles des services LPD, SMB
et AppSocket <em>(tel que JetDirect)</em> sont supportés avec des fonctionnalités
réduites.</p>
<p>CUPS ajoute la recherche d&rsquo;imprimantes réseaux et PPD (Description
d&rsquo;Imprimante PostScript) basé sur les options d&rsquo;impression supportées
dans le monde réel sous UNIX.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 les
paquets : <code>cups cups-filters cups-libs foomatic-db gutenprint</code></strong> <br>
<em>(<code>cups-pdf</code> en option)</em></p>
<h2 id="configuration">Configuration</h2>
<p>⇒ Depuis OpenBSD 6.5 : la version du driver Gutenprint a changé
(v5.3.x au lieu de v5.2.x) ; modifiez les paramètres de l&rsquo;imprimante
pour lui changer le pilote vers cette nouvelle version !</p>
<h3 id="shell">shell</h3>
<p>Depuis OpenBSD 6.2, les binaires <code>lpq</code>, <code>lpr</code>, et <code>lprm</code> ne sont plus
liés symboliquement à <code>/usr/bin</code>. Il est nécessaire de les utiliser en
les préfixant de <code>/usr/local/bin/</code>.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Pensez à éditer votre fichier <code>~/.kshrc</code>, afin de créer des alias qui
vous seront utiles, en ajoutant le code suivant :</p>
<p><code>for i in lpq lpr lprm; do alias $i=/usr/local/bin/$i; done</code></p>
<p>Vous pourrez ainsi les utiliser comme avant !</p>
</div>

<h3 id="découverte-des-services-multicast">Découverte des services multicast</h3>
<p>Pour la découverte des services multicast - mDNS <em>(de type <a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi (Découverte de services multicast DNS)</a>,
Bonjour, …)</em></p>
<h3 id="cups">Cups</h3>
<p>Il nous faut :</p>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer les services</a>
 <strong><code>cupsd cups_browsed</code></strong></li>
<li>puis les <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrer</a>
</li>
</ul>
<h3 id="règles-pf">Règles PF</h3>
<p>Voici les règles pare-feu si besoin :</p>
<ul>
<li>pour l&rsquo;accès à l&rsquo;interface web de Cups : <br>
<code>pass in on egress proto tcp from egress:network to egress port 631 flags S/SA modulate state</code></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ces règles sont à adapter à vos besoins, et ne sont pas nécessairement justes !</div>

<h2 id="administration">Administration</h2>
<h3 id="web">Web</h3>
<p>Cups, à ce moment, devrait être accessible par votre navigateur web
préféré, par exemple <a class="inside" href="/fr/sys/openbsd/firefox/" title="Lien interne vers l&#39;article : 'Firefox / OpenBSD'">Firefox</a>
,
sur : http://localhost:631</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">L&rsquo;interface d&rsquo;administration web de Cups est celle qui fonctionne assurément,
normalement. Entrez votre mot-de-passe root… et administrez !</div>

<h3 id="console">Console</h3>
<ul>
<li><code>cupsctl</code> : <code># cupsctl --share-printers</code></li>
<li><code>lpadmin</code> : <code># lpadmin -E -p printer_name -o printer-is-shared=false</code>
<ul>
<li>l&rsquo;option <code>-E</code> active le chiffrement des données avec le service ;
<em>elle est intégrée aussi aux autres outils ci-dessous</em>.</li>
<li>l&rsquo;option <code>printer-is-shared</code> permet de partager ou non l&rsquo;imprimante ;
<code>true</code> autorise, <code>false</code> ne le permet pas</li>
</ul>
</li>
<li><code>lpoptions</code> : affiche les options d&rsquo;une imprimante
<ul>
<li><code>-l</code> : version détaillée</li>
</ul>
</li>
<li><code>lpstat</code> : outil pour obtenir les informations sur les imprimantes
ou le serveur Cups
<ul>
<li><code>-l</code> : affiche une liste détaillée des imprimantes, des travaux
d&rsquo;impression, etc.</li>
<li><code>-p</code> : restitue toutes les informations de toutes les imprimantes
configurées ; pour cibler une seule, il suffit de donner son nom
en argument de l&rsquo;option, tel que dans la commande <code>lpadmin</code>
ci-dessus.</li>
<li><code>-r</code> : l&rsquo;état du serveur Cups</li>
<li><code>-t</code> : restitue toutes les informations d&rsquo;état</li>
</ul>
</li>
</ul>
<p>À toutes ces commandes, il existe pléthore d&rsquo;options, veuillez lire les
manpages correspondants.</p>
<p>Les deux premières commandes doivent avoir des droits d&rsquo;administration,
ce qui n&rsquo;est pas le cas des deux autres.</p>
<h3 id="interface-graphique">Interface Graphique</h3>
<p>Pour gérer les imprimantes en mode graphiques, il est nécessaire
d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

les packages suivants : <code>gtk+2-cups</code>, <code>gtk+3-cups</code> et/ou <code>gtk+4-cups</code>
selon votre bureau graphique.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il est possible que l&rsquo;administration ne soit pas complète, et de
rencontrer des problèmes pour installer une ou des imprimantes par ces
biais.</div>

<h2 id="gestion">Gestion</h2>
<h3 id="usb">USB</h3>
<h4 id="détection-imprimante-usb">Détection Imprimante USB</h4>
<p>Pour détecter votre imprimante usb, connectez-la sur un port usb, en
premier, puis exécuter dans un terminal, la commande suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># usbdevs -vd</span>
</span></span><span style="display:flex;"><span>Controller /dev/usb3:
</span></span><span style="display:flex;"><span>addr 1: full speed, self powered, config 1, UHCI root hub<span style="color:#5bc4bf">(</span>0x0000<span style="color:#5bc4bf">)</span>, Intel<span style="color:#5bc4bf">(</span>0x8086<span style="color:#5bc4bf">)</span>, rev 1.00
</span></span><span style="display:flex;"><span>uhub3
</span></span><span style="display:flex;"><span>port <span style="color:#f99b15">1</span> powered
</span></span><span style="display:flex;"><span>port <span style="color:#f99b15">2</span> addr 2: full speed, self powered, config 1, USB MFP<span style="color:#5bc4bf">(</span>0x082f<span style="color:#5bc4bf">)</span>, EPSON<span style="color:#5bc4bf">(</span>0x04b8<span style="color:#5bc4bf">)</span>, rev 1.00, iSerialNumber L83010704250947490
</span></span><span style="display:flex;"><span>ugen0
</span></span></code></pre></div><p>Il faut repérer sur la ligne <code>Controller /dev/usb</code> quel numéro est affiché
au périphérique <code>ugen</code> et <code>usb</code>, puis donner à ce périphérique les droits
nécessaires - dans ce cas-là :</p>
<p><code># chown _cups /dev/ugen0.* /dev/usb3</code></p>
<p>ou pour une <abbr title="Multi Functions Printer">MFP</abbr>
 (avec scanner
intégré :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># chown _cups:_saned /dev/ugen0.* /dev/usb3</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chmod 0660/dev/ugen0.* /dev/usb3</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Pour préserver ces changements, au prochain redémarrage, ajoutez la
commande à votre fichier <code>/etc/[rc.local](http://man.openbsd.org/rc.local)</code>.</p>
<p>Bien-sûr, modifiez le numéro des périphériques <code>ugen</code> et <code>usb</code> utilisés.</p>
<p>Une autre méthode est d&rsquo;utiliser les scripts <code>attach</code>/<code>detach</code> du service
<code>hotplugd</code> !</p>
</div>

<h4 id="configuration-imprimante-usb">Configuration Imprimante USB</h4>
<p>Pour pouvoir utiliser correctement votre imprimante sur port usb, il est
nécessaire de désactiver <a href="http://man.openbsd.org/ulpt.4" rel="external">ulpt(4)</a> du noyau
(cf: [config(8)]http://man.openbsd.org/config.8)), autrement votre
imprimante ne sera pas &ldquo;visible&rdquo;, car non disponible par le biais de la
bibliothèque <code>libusb</code>.</p>
<p>⇒ <strong>Depuis OpenBSD 7.0</strong>, il suffit de remplir/créer le fichier
<code>/etc/bsd.re-config</code> avec :<br>
<code>disable ulpt</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># echo &#39;disable ulpt&#39; &gt;&gt;/etc/bsd.re-config</span>
</span></span></code></pre></div><p>puis redémarrer la machine !</p>
<hr>
<p>⇒ <strong>Avant OpenBSD 7.0 :</strong></p>
<p>Pour cela, tapez : <br>
<code># printf 'disable ulpt\nq\n' | config -ef /bsd</code></p>
<p>Puis, relinker le noyau : <br>
<code># sha256 /bsd &gt;/var/db/kernel.SHA256</code></p>
<hr>
<h3 id="port-parallèle">Port parallèle</h3>
<p>Pour pouvoir imprimer sur une imprimante port parallèle, le service cups
a besoin d&rsquo;avoir accès aux périphériques spécifiques.</p>
<p>Exécutez la commande suivante : <br>
<code>chown _cups /dev/lp[a,t]0</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Pour préserver ces changements, au prochain redémarrage, ajoutez la
commande à votre fichier <code>/etc/rc.local</code> !</div>

<h3 id="imprimante-partagée">Imprimante partagée</h3>
<h4 id="par-mdns">Par mDNS</h4>
<p>Il est nécessaire qu&rsquo;<a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi (Découverte de services multicast DNS)</a> soit installé
et fonctionnel ; de même, le service <code>cups_browsed</code> doit être actif sur
votre station !</p>
<p>Elle peut être administrée soit par l&rsquo;interface
d&rsquo;administration web de Cups, soit avec des droits administrateurs…</p>
<h4 id="en-utilisant-dns-sd">En utilisant DNS-SD</h4>
<p>Veuillez lire le fichier pkg-readme de cups !</p>
<hr>
<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de <strong>lire le fichier</strong> :</p>
<ul>
<li><code>/usr/local/share/doc/pkg-readmes/cups</code>,</li>
<li><code>/usr/local/share/doc/pkg-readmes/cups-filters</code>,</li>
<li>et au cas où : <code>/usr/local/share/doc/pkg-readmes/cups-pdf</code>, ainsi que sous <code>/usr/local/share/doc/cups-pdf/README</code>.</li>
<li>voire aussi : <code>/usr/local/share/doc/pkg-readmes/foomatic-db-engine</code>.</li>
</ul>
<h3 id="manpage">manpage</h3>
<p>Depuis OpenBSD 6.2, l&rsquo;accès aux pages de manuel est sensiblement différent :</p>
<p><code>man -m /usr/local/man lpr</code></p>
<p>Cela est vrai pour les binaires <code>lpq</code>, <code>lpr</code> et <code>lprm</code> !</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer les impressions sous OpenBSD, grâce au projet CUPS]]></summary>
        <published>2020-01-19T13:47:35+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:297e28c3-0c44-a289-614e-65654571db28</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/cabal/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Installer l&#39;outil Cabal sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="cabal" scheme="http://doc.huc.fr.eu.org/fr/tags/cabal/" />
        <category term="haskell" scheme="http://doc.huc.fr.eu.org/fr/tags/haskell/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le programme en ligne de commande <code>cabal</code>  simplifie le processus de
gestion des logiciels Haskell en automatisant la récupération, configuration,
compilation et installation des programmes et bibliothèques Haskell.</p>
<ul>
<li>architectures gérées : aarch64, amd64, i386</li>
<li>mainteneur : Matthias Kilian</li>
<li>Openports : <a href="https://openports.pl/path/devel/cabal-install" rel="external">https://openports.pl/path/devel/cabal-install</a></li>
<li>site web officiel : <a href="http://www.haskell.org/cabal/" rel="external">http://www.haskell.org/cabal/</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>cabal-install</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Du fait de la protection mémoire W^X, l&rsquo;outil <code>cabal</code> ne fonctionne pas
correctement. Pour résoudre cette situation, deux manières de faire :</p>
<h3 id="modifications-système">Modifications système</h3>
<p>Pour remédier à la situation, nous allons modifier légèrement votre
<code>$HOME</code> et <code>/usr/local</code>.</p>
<ul>
<li>Création des répertoires nécessaires dans <code>/usr/local</code>, avec les
droits administrateurs</li>
<li>Attribution des droits utilisateurs nécessaires, toujours avec des
droits administrateurs</li>
<li>Suppression du répertoire ad hoc dans <code>$HOME</code></li>
<li>et, lien symbolique</li>
<li>création d&rsquo;un alias utile</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># mkdir -p /usr/local/cabal/build</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chown -R user:wheel /usr/local/cabal</span>
</span></span><span style="display:flex;"><span>$ rm -rf ~/.cabal
</span></span><span style="display:flex;"><span>$ ln -s /usr/local/cabal ~/.cabal
</span></span></code></pre></div><p>Pour finir, créez donc un alias dans votre fichier personnel <code>.khsrc</code>,
ou <code>.profile</code> : <br>
<code>alias cabal='env TMPDIR=/usr/local/cabal/build/ cabal'</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Ajouter le dossier .cabal à votre variable PATH pour pouvoir lancer les
commandes facilement !</p>
<p><code>PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:$HOME/.cabal/bin</code></p>
</div>

<h3 id="option-wxallowed">Option wxallowed</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Prenez conscience qu&rsquo;utiliser cette possibilité aura pour conséquence de
permettre l&rsquo;exécution de binaire potentiellement dangereux depuis votre
<code>$HOME</code>.</p>
<p><strong>Mieux vaut éviter</strong> !</p>
</div>

<p>Il est possible d&rsquo;ajouter l&rsquo;option de montage <code>wxallowed</code> à votre partition
$HOME si vous l&rsquo;avez créée.</p>
<hr>
<p>source : <a href="https://deftly.net/posts/2017-10-12-using-cabal-on-openbsd.html" rel="external">https://deftly.net/posts/2017-10-12-using-cabal-on-openbsd.html</a></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installation, configuration de l&#39;outil &#39;cabal&#39; pour la gestion des programmes et bibliothèques Haskell, sous OpenBSD]]></summary>
        <published>2020-01-19T13:45:21+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d8f7c009-efee-d743-5f8f-62d865a4f745</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sane/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SANE : scannérisons des documents sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="SANE" scheme="http://doc.huc.fr.eu.org/fr/tags/sane/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>SANE</strong> signifie <strong>Scanner Access Now Easy</strong> - <em>que l&rsquo;on pourait traduire
par : Scannérisation Facile</em></p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>sane-backends</code></strong>.</p>
<p>Ce paquet contient les bibliothèques SANE (le backend et la partie réseau)
ainsi que l&rsquo;outil en ligne de commande <code>scanimage</code>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="usb">USB</h3>
<p>Puisque la scannerisation par USB peut être gérée par la bibliothèque
<code>libusb</code>, nous avons besoin d&rsquo;autoriser l&rsquo;utilisateur <code>_saned</code> au point
de montage USB correspondant.</p>
<p>Trouvez où votre scanner est attaché : <br>
<code># usbdevs -vd </code> <br>
afin de changer les droits appropriés.</p>
<p>Pour l&rsquo;exemple suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Controller /dev/usb3:
</span></span><span style="display:flex;"><span>addr 1: full speed, self powered, config 1, UHCI root hub<span style="color:#5bc4bf">(</span>0x0000<span style="color:#5bc4bf">)</span>, Intel<span style="color:#5bc4bf">(</span>0x8086<span style="color:#5bc4bf">)</span>, rev 1.00
</span></span><span style="display:flex;"><span>  uhub3
</span></span><span style="display:flex;"><span> port <span style="color:#f99b15">1</span> powered
</span></span><span style="display:flex;"><span> port <span style="color:#f99b15">2</span> addr 2: full speed, self powered, config 1, USB MFP<span style="color:#5bc4bf">(</span>0x082f<span style="color:#5bc4bf">)</span>, EPSON<span style="color:#5bc4bf">(</span>0x04b8<span style="color:#5bc4bf">)</span>, rev 1.00, iSerialNumber L83010704250947490
</span></span><span style="display:flex;"><span>   ugen0
</span></span></code></pre></div><p>il vous faudra utiliser : <code># chgrp _saned /dev/ugen0.* /dev/usb3</code>
sur le périphérique <code>/dev/usb3</code>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>La raison pour laquelle nous changeons le groupe et non pas l&rsquo;utilisateur
est que cela permet à des périphériques multi-fonctions de fonctionner à
la fois pour l&rsquo;impression et pour la scannérisation.</p>
<p><em>(par exemple, en appartenant à <code>_cups:_saned</code>).</em></p>
</div>

<p>Pour préserver vos changements après une mise à niveau du système :</p>
<ul>
<li>utilisez <a href="https://man.openbsd.org/rc.local.8" rel="external">rc.local(8)</a> - par exemple
pour une imprimante multi-fonctions, ajoutez la ligne suivante : <br>
<code>chown _cups:_saned /dev/ugen0.* /dev/usb1</code></li>
<li>alternativement les scripts <code>attach</code> et <code>detach</code>
d&rsquo;<a href="https://man.openbsd.org/hotplugd.8" rel="external">hotplugd(8)</a> peuvent l&rsquo;automatiser.</li>
</ul>
<p>Vous pouvez aussi garantir l&rsquo;accès direct au scanner en ajoutant les
utilisateurs au groupe <code>_saned</code>.</p>
<h3 id="réseau">Réseau</h3>
<p>Par défaut, le service saned(8) fonctionne en tant que <code>_saned</code>, ainsi
vous devez autoriser l&rsquo;utilisateur <code>_saned</code> a accéder au nœud du périphérique
du scanner.</p>
<h3 id="scsi">SCSI</h3>
<p>SANE prend en charge seulement les périphériques supportés par le pilote
SCSI générique <a href="https://man.openbsd.org/uk.4" rel="external">uk(4)</a>.</p>
<p>Assurez-vous que votre utilisateur ait les accès sur le nœud du périphérique
du scanner, sinon, vous ne serez pas capable de scanner.</p>
<h3 id="verrouillage-fichier">Verrouillage fichier</h3>
<p>Certains backends <em>(tel que sane-plustek(5))</em> utilisent un verrouillage
fichier (lockfile) pour permettre les accès multiples au scanner. Si vous
utilisez de tels backends, vous devez vous ajouter au groupe <code>_saned</code>,
sinon vous ne serez pas capable de scanner.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/sane-backends</code></li>
<li>La documentation <code>/usr/local/share/doc/sane-backends/</code>
<ul>
<li>SURTOUT celle liée aux différents problèmes : <code>/usr/local/share/doc/sane-backends/PROBLEMS</code></li>
</ul>
</li>
<li>Les exemples : <code>/usr/local/share/exemples/sane-backends/</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utilisons un scanner sous OpenBSD avec le projet SANE pour scanner des documents]]></summary>
        <published>2020-01-19T13:35:42+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c1d829ec-af23-5c18-a6fa-61751e6443a2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/inkscape/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: inkscape</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="inkscape" scheme="http://doc.huc.fr.eu.org/fr/tags/inkscape/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Inkscape est un logiciel d&rsquo;édition de graphisme vectoriel utilisant le format de fichier SVG, norme du W3C.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>inkscape</code></strong>.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/inkscape</code></li>
</ul>
<h2 id="gestion-des-extensions-ruby">Gestion des extensions Ruby</h2>
<p>Aucune extension écrite dans le langage Ruby n&rsquo;est fournie avec le paquet Inkscape.</p>
<p>Si vous voulez en installer, ou en écrire, il vous faudra
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

d&rsquo;abord le langage Ruby :</p>
<ul>
<li>Ruby <strong>2.6</strong> - le paquet <code>ruby-2.6</code>, pour OpenBSD <strong>6.6</strong>, <strong>6.7</strong></li>
<li>Ruby <strong>2.5</strong> - le paquet <code>ruby-2.5.5</code>, au minimum, pour OpenBSD <strong>6.5</strong>.</li>
<li>Ruby <strong>2.4</strong> - le paquet <code>ruby-2.4.4</code>, au minimum, pour OpenBSD <strong>6.4</strong>.</li>
</ul>
<h2 id="bogue">Bogue</h2>
<h3 id="icône">Icône</h3>
<p>Inkscape n&rsquo;est pas résilient sur l&rsquo;oubli du paramétrage de l&rsquo;icône et
peut crasher
<em>(par exemple, lors de l&rsquo;ouverture du menu fichier &gt; &ldquo;Propriétés du document&rdquo;)</em></p>
<p>Si vous voulez spécifier un icône personnalisé dans votre thème
<code>~/.gtkrc-2.0</code>, veuillez d&rsquo;abord vous assurer de la présence effective
sur votre système de fichiers et de sa bonne localisation !</p>
<p><em>Bogue #<a href="https://bugs.launchpad.net/inkscape/+bug/1238142" rel="external">1238142</a></em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installation du logiciel &#39;inkscape&#39; sous OpenBSD]]></summary>
        <published>2020-01-19T13:30:37+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:fb998062-b17f-8e9b-f88e-2f1101d68717</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/ffmpeg/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: FFmpeg / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="FFmpeg" scheme="http://doc.huc.fr.eu.org/fr/tags/ffmpeg/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>FFmpeg</strong> est une solution complète pour enregistrer, convertir et
émettre des flux audio et vidéo. Il inclut la principale bibliothèque de
codec audio et vidéo libavcodec.</p>
<ul>
<li>Site officiel : <a href="https://ffmpeg.org" rel="external">https://ffmpeg.org</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>ffmpeg</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="périphériques-brooktree">Périphériques Brooktree</h3>
<p>Les périphériques de capture vidéo et tuners TV de la marque Brooktree
sont gérés par le pilote <a href="http://man.openbsd.org/bktr.4" rel="external">bktr(4)</a>, seulement
pris en charge sur les architectures amd64, i386 et powerpc.</p>
<p>Ils peuvent être contrôlés au moyen des variables d&rsquo;environnements suivantes :</p>
<ul>
<li><code>BKTR_DEV=</code>{0|1|2|3|4} en sélectionnant le périphérique d&rsquo;entrée adéquat
(relatif au tuner, la caméra, etc…)</li>
<li><code>BKTR_FORMAT=</code>{1|2|3|4|5|6} où :
<ul>
<li>1 : PAL</li>
<li>2 : NTSC</li>
<li>3 : SECAM</li>
<li>4 : PALN</li>
<li>5 : PALM</li>
<li>6 : NTSCJ</li>
</ul>
</li>
<li><code>BKTR_FREQUENCY=</code>xxx.yy où <strong>xxx.yy</strong> représente la fréquence à
paramétrer en Mhz.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>N&rsquo;oubliez pas de lire le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/ffmpeg</code> !</p>
<p>Vous pouvez lire aussi :</p>
<ul>
<li>la documentation à-propos : <code>/usr/local/share/doc/ffmpeg</code></li>
<li>et des exemples dans : <code>/usr/local/share/examples/ffmpeg</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser sous OpenBSD l&#39;outil `FFmpeg&#39;, un outil de gestion audio et vidéo.]]></summary>
        <published>2020-01-19T13:19:19+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:267caa49-9ffa-aefb-06ec-fc21fda988cd</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/qemu/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Qemu : Virtualisation sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="qemu" scheme="http://doc.huc.fr.eu.org/fr/tags/qemu/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>QEMU</strong> est un émulateur machine open source. Il peut exécuter des
systèmes d&rsquo;exploitations et des programmes faits pour une machine (càd,
une carte ARM) sur une machine différente (càd, votre propre PC).</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <code>qemu</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="démarrage-rapide">Démarrage rapide</h3>
<h4 id="obtenez-une-image-iso">Obtenez une image ISO</h4>
<ul>
<li>Pour i386 : <br>
<code>$ ftp ftp://ftp.openbsd.org/pub/OpenBSD/snapshots/i386/cd52.iso</code></li>
<li>ou respectivement pour amd64 : <br>
<code>$ ftp ftp://ftp.openbsd.org/pub/OpenBSD/snapshots/amd64/cd52.iso</code></li>
<li>voire SPARC : <br>
<code>$ ftp ftp://ftp.openbsd.org/pub/OpenBSD/snapshots/sparc/cd52.iso</code></li>
</ul>
<h4 id="créez-un-disque-virtuel">Créez un disque virtuel</h4>
<p><code>$ qemu-img create -f qcow2 virtual.img 10G</code></p>
<h4 id="installez-le-système-dexploitation">Installez le système d&rsquo;exploitation</h4>
<ul>
<li>pour i386 : <br>
<code>$ qemu-system-i386 -m 32 -monitor stdio -no-fd-bootchk -hda virtual.img -cdrom cd52.iso -boot d</code></li>
<li>pour amd64 : <br>
<code>$ qemu-system-x86_64 -m 32 -monitor stdio -no-fd-bootchk -hda virtual.img -cdrom cd52.iso -boot d</code></li>
<li>pour SPARC : <br>
<code>$ qemu-system-sparc -m 32 -monitor stdio -hda virtual.img -cdrom cd52.iso -boot d</code></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Notes :</p>
<ul>
<li>Démarrez dans un terminal <code>xterm</code> ou équivalent.</li>
<li>Assurez-vous de choisir la console série durant l&rsquo;installation</li>
<li>l&rsquo;option <code>-no-fd-bootchk</code> permet un démarrage plus rapide quand il
n&rsquo;y a pas de lecteur disquette
<ul>
<li>ce n&rsquo;est pas supporté par <code>qemu-system-sparc</code>.</li>
</ul>
</li>
<li><code>qemu-system-ppc*</code> et <code>qemu-system-sparc*</code> échoue actuellement avec
l&rsquo;usage des drapeaux malloc <code>J</code> ou <code>S</code></li>
</ul></div>

<h4 id="compressez-le-disque-virtuel">Compressez le disque virtuel</h4>
<p><code>$ qemu-img convert -c -O qcow2 virtual.img v.tmp &amp;&amp; mv v.tmp virtual.img</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Note : Ne pas faire cela pendant que QEMU fonctionne ou utilise le disque
virtuel</div>

<h4 id="démarrez-normalement-le-disque-virtuel">Démarrez normalement le disque virtuel</h4>
<ul>
<li>Pour i386 : <br>
<code>$ qemu-system-i386 -m 32 -nographic -no-fd-bootchk -hda virtual.img</code></li>
<li>Pour amd64 : <br>
<code>$ qemu-system-x86_64 -m 32 -nographic -no-fd-bootchk -hda virtual.img</code></li>
<li>Pour SPARC : <br>
<code>$ qemu-system-sparc -m 32 -nographic -hda virtual.img</code></li>
</ul>
<h3 id="gestion-du-réseau">Gestion du réseau</h3>
<h4 id="paramétrage-par-défaut">Paramétrage par défaut</h4>
<p>Par défaut, QEMU définit les paramètres réseaux suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">-net nic,vlan</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0,model=e1000,macaddr=52:54:00:12:34:56</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">-net user,vlan</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0</span>
</span></span></code></pre></div><p>De même, à l&rsquo;intérieur du mode réseau virtuel, il utilise le segment
<code>10.0.2.0/24</code> et dessert DHCP à l&rsquo;intérieur du réseau virtuel.
Des adresses statiques peuvent être utilisées s&rsquo;il n&rsquo;est pas possible
d&rsquo;utiliser DHCP dans l&rsquo;hôte invité :</p>
<ul>
<li>IP du système hôte     : 10.0.2.15</li>
<li>Passerelle par défaut : 10.0.2.2</li>
<li>Serveur de nom      : 10.0.2.3</li>
</ul>
<p>C&rsquo;est suffisant pour la plupart des opérations, QEMU assume la NAT lui-même
et permet au réseau de l&rsquo;espace utilisateur de faire des opérations
TCP/UDP. ICMP et autres aspects réseaux ne sont pas possible dans ce mode.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">NOTE : Si vous utilisez l&rsquo;argument <code>-net</code> en ligne de commande, QEMU
présume que vous savez ce que vous faîtes et nettoie les valeurs par défaut
pour le reste des paramètres par défaut <code>-net</code>.</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">NOTE : le réseau du mode invité ne supporte pas actuellement IPv6, QEMU
se plaindra s&rsquo;il ne peut pas trouver de serveur DNS, si <code>/etc/resolv.conf</code>
contient seulement des serveurs DNS IPv6.</div>

<h4 id="mode-tap">Mode tap</h4>
<p>Parfois il est souhaitable de configurer QEMU pour accéder au réseau
directement via la Couche de niveau 2. Une manière de faire cela sans
exécuter QEMU avec les droits root est de laisser root ouvrir le
périphérique <code>/dev/tapN</code> et de passer le fichier descripteur à QEMU.
L&rsquo;interface <a href="https://man.openbsd.org/tap.4" rel="external">tap(4)</a> devrait être de
préférence configurée avant de démarrer QEMU : <br>
<code># ifconfig tap0 192.168.0.254</code></p>
<p>L&rsquo;interface peut aussi être configurée comme partie de
<a href="ttps://man.openbsd.org/bridge.4" rel="external">bridge(4)</a>, dans ce cas l&rsquo;adresse ip
peut être omise : <br>
<code># ifconfig bridge0 add tap0 add em0 up</code></p>
<p>Les interfaces tunnel et bridge peuvent aussi être configurées au démarrage
du système en éditant les fichiers <code>/etc/hostname.tapN</code> et
<code>/etc/hostname.bridgeN</code>, respectivement
<em>(voir <a href="https://man.openbsd.org/hostname.if.5" rel="external">hostname.if(5)</a>)</em>.</p>
<p>Après la configuration du réseau virtuel, nous pouvons utiliser <code>doas</code>
pour laisser root ouvrir le périphérique tunnel et ensuite utiliser encore
<code>doas</code> pour supprimer les privilèges et démarrer QEMU :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas sh -c <span style="color:#48b685">&#34;doas -u </span><span style="color:#ef6155">$USER</span><span style="color:#48b685"> qemu-system-i386 -nographic -net nic -net tap,fd=3 -no-fd-bootchk -hda virtual.img 3&lt;&gt;/dev/tap0&#34;</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>NOTE : si vous utilisez <code>sudo</code> à la place de <code>doas</code>, souvenez vous que
sudo appelle <a href="https://man.openbsd.org/closefrom.2" rel="external"><code>closefrom(2)</code></a>.
Avant d&rsquo;avoir plus d&rsquo;un <code>fd</code> passant l&rsquo;interface <code>tap</code>, ajouter une ligne
à <code>sudoers</code> ressemblant à : <br>
<code>Defaults closefrom_override</code> <br>
et appeler <code>sudo</code> via <code>sudo -C 5 -u $USER qemu-system-i386 …</code> est requis.</p>
<p><em>Voir <a href="https://man.openbsd.org/sudoers.5" rel="external">sudoers(5)</a> et <a href="https://man.openbsd.org/sudo.8" rel="external">sudo(8)</a> pour les détails</em>.</p>
</div>

<p>Une alternative à la procédure décrite ci-dessus est de laisser QEMU
paramétrer le réseau via le fichier <code>/etc/qemu-ifup</code>. Ceci n&rsquo;est toutefois
pas recommandé, puisque vous allez exécuter QEMU avec les droits root,
et qu&rsquo;il n&rsquo;y a pas de moyen de supprimer les privilèges root à ce niveau.</p>
<p><code>/etc/qemu-ifup</code> contient quelques paramètres par défaut qui permettent
de faire ce qui suit : <br>
<code># qemu-system-i386 -net nic -net tap -no-fd-bootchk -hda virtual.img</code></p>
<p>Cela présume que vous souhaitez que l&rsquo;interface <a href="https://man.openbsd.org/tap.4" rel="external">tap(4)</a>
discute avec l&rsquo;interface gérant la route IPv4 par défaut (basculant sur
<code>trunk0</code> si aucune route n&rsquo;est trouvée), et que vous voulez que <code>bridge0</code>
soit utilisée en tant que bridge en second.</p>
<p>Paramétrer les variables d&rsquo;environnement <code>ETHER</code> et <code>BRIDGE</code> surchargera
ces paramètres, respectivement.</p>
<p>Lors du démarrage de QEMU, le script essaie de sortir les informations
utiles, mais il peut y avoir des messages d&rsquo;erreurs qui apparaissent,
aussi bien. Sur mon laptop, je veux router NAT nativement en utilisant PF
et aussi en ayant accès à la couche de niveau 2 vers le réseau de QEMU.
J&rsquo;ai donc ceci dans le fichier <code>/etc/hostname.trunk101</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">inet6 fe80::1c 64 lladdr 00:03:25:0d:7a:2c</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inet 10.7.255.1 255.255.255.0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inet6 alias 2001:240:58a:45::1c</span>
</span></span></code></pre></div><p>J&rsquo;ai configuré dhcpd pour s&rsquo;exécuter sur trunk101, et aussi rad.</p>
<p>Pour QEMU, le démarrage ressemble à cela :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># export ETHER=trunk101</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># export BRIDGE=bridge101</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># qemu-system-i386 -net nic,vlan=0,macaddr=52:54:00:12:35:00 \</span>
</span></span><span style="display:flex;"><span>	-net tap,vlan<span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> -vnc :0 -localtime -usb -usbdevice tablet <span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span>	-m <span style="color:#f99b15">256</span> -no-fd-bootchk -hda virtual.img -monitor stdio
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span>tap0 <span style="color:#5bc4bf">(</span>bridge101 &lt;-&gt; trunk101<span style="color:#5bc4bf">)</span>ifconfig: bridge101: No such process
</span></span><span style="display:flex;"><span>    ifconfig: bridge101: No such process
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>qemu<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Ces erreurs sont normales et doivent être ignorées. Vérifiez que le réseau
est proprement configurée en vérifiant l&rsquo;interface bridge :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ifconfig bridge101
</span></span><span style="display:flex;"><span>bridge101: <span style="color:#ef6155">flags</span><span style="color:#5bc4bf">=</span>41&lt;UP,RUNNING&gt;
</span></span><span style="display:flex;"><span>groups: bridge
</span></span><span style="display:flex;"><span>priority <span style="color:#f99b15">32768</span> hellotime <span style="color:#f99b15">2</span> fwddelay <span style="color:#f99b15">15</span> maxage <span style="color:#f99b15">20</span> holdcnt <span style="color:#f99b15">6</span> proto rstp
</span></span><span style="display:flex;"><span>designated: id 00:00:00:00:00:00 priority <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>tap0 <span style="color:#ef6155">flags</span><span style="color:#5bc4bf">=</span>3&lt;LEARNING,DISCOVER&gt;
</span></span><span style="display:flex;"><span>	port <span style="color:#f99b15">16</span> ifpriority <span style="color:#f99b15">0</span> ifcost <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>trunk101 <span style="color:#ef6155">flags</span><span style="color:#5bc4bf">=</span>3&lt;LEARNING,DISCOVER&gt;
</span></span><span style="display:flex;"><span>	port <span style="color:#f99b15">6</span> ifpriority <span style="color:#f99b15">0</span> ifcost <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>Addresses <span style="color:#5bc4bf">(</span>max cache: 100, timeout: 240<span style="color:#5bc4bf">)</span>:
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">NOTE : Lors de l&rsquo;exécution de sessions multiples simultanées sur le même
bridge, il faut faire attention car l&rsquo;adresse MAC du réseau par défaut
est <code>52:54:00:12:34:56</code> pour chaque instance QEMU. Pour changer cela,
observez la syntaxe <code>macaddr=</code> dans l&rsquo;exemple ci-dessus et choisissez un
<code>lladdr</code> unique par interface QEMU.</div>

<h3 id="gestion-de-la-souris">Gestion de la souris</h3>
<p>NOTE : Certains systèmes d&rsquo;exploitation fonctionnent mieux avec le périphérique
USB <code>tablet</code> qu&rsquo;avec le périphérique normal de souris PS/2.
Voir l&rsquo;exemple ci-dessus pour l&rsquo;usage.</p>
<p><code>-usb -usbdevice tablet</code></p>
<h3 id="gestion-de-la-console-série">Gestion de la console série</h3>
<p>Installer OpenBSD via la console série est parfois désirable. X peut ne
pas être disponible… Il y a deux manières d&rsquo;accomplir cela, les deux
offrant la même solution :</p>
<p>a. <code>qemu-system-i386 -vnc :0 -serial stdio .. virtual.img -cdrom install52.iso -boot d</code></p>
<ul>
<li>cette option vous permet d&rsquo;utiliser VNC depuis tout système pour vous
connecter à l&rsquo;instance QEMU et d&rsquo;utiliser <code>set tty com0</code> à l&rsquo;invite
<code>boot&gt;</code>.</li>
<li>vous pouvez alors déconnecter VNC et utiliser le terminal avec lequel
vous avez démarré QEMU pour faire l&rsquo;installation.</li>
</ul>
<p>b. <code>qemu-system-i386 -nographic .. virtual.img -fda floppy52.fs -boot a</code></p>
<ul>
<li>cela mappe à la fois le port série et l&rsquo;invite du moniteur (qemu) sur
le terminal où QEMU a été démarré.</li>
<li>pour basculer entre eux, utilisez <key>Ctrl-a c</key>
<ul>
<li>lire la page de manuel QEMU pour les autres commandes qui fonctionnent dans le mode <code>-nographic</code>.</li>
</ul>
</li>
<li>la préparation de l&rsquo;image de disquette pour forcer le mode de console
série est simple : <br></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>vnconfig vnd0 floppy52.fs
</span></span><span style="display:flex;"><span>mount /dev/vnd0c /mnt
</span></span><span style="display:flex;"><span>mkdir /mnt/etc
</span></span><span style="display:flex;"><span>echo set tty com0 &gt; /mnt/etc/boot.conf
</span></span><span style="display:flex;"><span>umount /mnt
</span></span><span style="display:flex;"><span>vnconfig -u vnd0
</span></span></code></pre></div><ul>
<li>Assurez-vous de choisir <code>yes</code> pour paramétrer <code>com0</code> en tant que console série.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">NOTE : L&rsquo;arrêt d&rsquo;OpenBSD fonctionne avec QEMU, ce qui provoque effectivement
la sortie de QEMU. C&rsquo;est une bonne chose, car il n&rsquo;est actuellement pas
possible de définir le périphérique de blocage à partir duquel QEMU est
démarré au moment de l&rsquo;exécution. Par conséquent, si vous démarrez une
installation à partir d&rsquo;un CD-ROM, vous démarrerez toujours à partir d&rsquo;un
CD-ROM chaque fois que vous redémarrerez cette session QEMU jusqu&rsquo;à ce
que vous quittiez et redémarriez QEMU à partir du disque dur virtuel.</div>

<h3 id="gestion-du-service">Gestion du service</h3>
<p>Parfois, vous voulez que QEMU démarre en tant que script système.</p>
<p>En plus des options ci-dessus, l&rsquo;option <code>-daemonize</code> est très pratique,
de même que pour désigner <code>telnet:</code> pour <code>-serial</code> et <code>-monitor</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">hddir</span><span style="color:#5bc4bf">=</span>/var/vm
</span></span><span style="display:flex;"><span><span style="color:#ef6155">USER</span><span style="color:#5bc4bf">=</span>qemu
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -x /usr/local/bin/qemu <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    echo -n <span style="color:#48b685">&#39;Qemu: vmi386&#39;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#5bc4bf">(</span>
</span></span><span style="display:flex;"><span>            ifconfig bridge101 add trunk101 add tap0 up
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            sh -c <span style="color:#48b685">&#34;doas -u </span><span style="color:#ef6155">$USER</span><span style="color:#48b685"> \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                /usr/local/bin/qemu-system-i386 \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -daemonize \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -nographic \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -net nic,vlan=0,macaddr=52:54:00:4e:62:8f \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -net tap,vlan=0,fd=3 \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -m 128 \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -hda </span><span style="color:#ef6155">$hddir</span><span style="color:#48b685">/virtual.img \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -serial telnet:127.0.0.1:1080,server,nowait \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -monitor telnet:127.0.0.1:1081,server,nowait \
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                -no-fd-bootchk 3&lt;&gt;/dev/tap0&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#48b685">&#34;.&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">NOTE : cela présume que l&rsquo;utilisateur <code>qemu</code> existe, créez-le ou paramétrez
<code>USER=</code> en lui donnant un utilisateur existant pour utiliser cet exemple.</div>

<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Lire le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/qemu</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement de manière collaborative cette documentation
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Virtualisation de système d&#39;exploitations, grâce à qemu, sous OpenBSD]]></summary>
        <published>2020-01-19T12:49:07+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:32cb4ea8-d26b-9ac0-da27-77fd2a1cd1e2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/memcached/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: memcached / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="memcached" scheme="http://doc.huc.fr.eu.org/fr/tags/memcached/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://www.memcached.org/" rel="external">memcached</a></strong> est un service de mise en
cache d&rsquo;objet mémoire flexible conçu pour alléger la charge des bases de
données dans les applications Web dynamiques en stockant des objets en
mémoire.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet &lsquo;&lsquo;memcached&rsquo;&rsquo;</strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Pour améliorer la &ldquo;sécurité&rdquo; du service :</p>
<ul>
<li>
<p><a class="inside" href="/fr/sys/openbsd/rcctl/#param%c3%a9trer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Paramétrons</a>

le service <code>memcached</code> pour n&rsquo;utiliser que l&rsquo;utilisateur <code>_memcached</code>,
l&rsquo;interface locale, et interdire toute activité UDP :<br>
<code>&quot;-u _memcached -l 127.0.0.1 -U 0&quot;</code></p>
</li>
<li>
<p><a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Démarrons le service</a>
 <strong>memcached</strong>.</p>
</li>
</ul>
<h3 id="règles-pf">Règles PF</h3>
<p>Il est possible d&rsquo;utiliser la règle PF suivante pour interdire toute
connexion sur le port d&rsquo;écoute du service de memcached :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">block in log on egress proto tcp to egress port 11211</span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<p>La principale documentation est le manpage :</p>
<p><code>$ man memcached</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[memcached, un service de cache mémoire pour base de données sous OpenBSD]]></summary>
        <published>2020-01-19T12:30:03+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e2a9bcf5-e921-27fc-6ff8-1faccdf01a24</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-depannage/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD - Dépannage</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Dépannage" scheme="http://doc.huc.fr.eu.org/fr/tags/d%C3%A9pannage/" />
        <content type="html"><![CDATA[<h2 id="horloge-matérielle-défectueuse">Horloge matérielle défectueuse</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Ce problème existait sous OpenBSD 6.3, 6.4.</p>
<p>Il semble que cela soit corrigé depuis OpenBSD 6.6 !</p>
</div>

<p>Votre clavier dysfonctionne et accentue de plusieurs fois la touche
appuyée sans que vous désiriez la doubler.</p>
<p><em>Ne cherchez pas à modifier vos paramétrages clavier - ce n&rsquo;est pas
votre clavier qui pose problème en réalité !</em></p>
<p>C&rsquo;est l&rsquo;horloge matérielle par défaut * tsc*  qui dans certains cas pose
ce problème - que votre architecture soit basée sur un CPU Intel ou AMD
n&rsquo;y change rien.</p>
<p>Il est nécessaire de la changer pour choisir <code>acpihpet0</code>  :</p>
<p><code>sysctl -w kern.timecounter.hardware=acpihpet0</code></p>
<p>Pour que le changement soit permanent, veuillez créer, avec des droits
administrateurs, si ce n&rsquo;est pas déjà fait, le fichier <code>/etc/sysctl.conf</code><br>
pour y ajouter <code>kern.timecounter.hardware=acpihpet0</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour se dépanner sous OpenBSD]]></summary>
        <published>2020-01-19T08:07:13+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8cd3b8fd-1954-75dd-bb0a-8053260d7a0d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-wifi/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion du Wifi / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Wifi" scheme="http://doc.huc.fr.eu.org/fr/tags/wifi/" />
        <content type="html"><![CDATA[<h2 id="configuration">Configuration</h2>
<p>Créez un fichier <code>/etc/hostname.interface</code> - <em>où <code>interface</code> est le nom
de l&rsquo;interface réseau</em> - et remplissez-le avec les informations suivantes.</p>
<hr>
<p>Exemple de fichier <code>/etc/hostname.rtwn0</code> :</p>
<h3 id="openbsd--69">OpenBSD ≥ 6.9</h3>
<p>Depuis OpenBSD 6.9, le démon <a href="https://man.openbsd.org/dhcpleased" rel="external">dhcpleased(8)</a>
est apparu, pour gérer le protocole dhcpd sur les stations clientes.</p>
<p>Utiliser la configuration <code>autoconf</code> plutôt que <code>dhcp</code>, tel que pour
l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">nwid nom_du_point_d_acces wpakey cle_wpa_impossible_à_deviner</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inet autoconf</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inet6 autoconf</span>
</span></span></code></pre></div><p>Selon le manpage <a href="https://man.openbsd.org/hostname.if.5#DYNAMIC_ADDRESS_CONFIGURATION" rel="external">hostname.if(5)</a>
actuel, le terme <code>dhcp</code> est/devient l&rsquo;abbréviation de la commande
<code>inet autoconf</code>.</p>
<h3 id="openbsd--64">OpenBSD ≥ 6.4</h3>
<p>Conformément au <a href="https://www.openbsd.org/faq/upgrade64.html#ConfigChanges" rel="external">changement de syntaxe et recommandation faites depuis OpenBSD 6.4</a>,
le mot clé <code>wpakey</code> doit être sur la même ligne que le mot clé <code>nwid</code> ou
<code>join</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">nwid nom_du_point_d_acces wpakey cle_wpa_impossible_à_deviner</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">dhcp</span>
</span></span></code></pre></div><h3 id="openbsd--63">OpenBSD ≤ 6.3</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">nwid nom_du_point_d_acces</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">wpa-key cle_wpa_impossible_à_deviner</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">dhcp</span>
</span></span></code></pre></div><h3 id="empêcher-la-déconnexion">Empêcher la déconnexion</h3>
<p>Ajouter à votre fichier de configuration, le flag : <code>nwflag stayauth</code></p>
<h2 id="trouver-un-ap">Trouver un AP</h2>
<p>Pour (re?)trouver votre point d’accès, exécutez : <br>
<code># ifconfig rtwn0 scan</code></p>
<h2 id="exemples">Exemples</h2>
<p>Retrouvez ci-dessous des exemples de configuration - <strong>à adapter à vos besoins</strong> !</p>
<h3 id="autoriser-un-utilisateur-à-manipuler-une-carte-wifi-pour-se-connecter">Autoriser un utilisateur à manipuler une carte wifi pour se connecter</h3>
<p>Pour trouver et me connecter facilement aux différents réseaux wifi,
je me suis créé un petit script.</p>
<p>Il est rudimentaire et peut être amélioré mais il fonctionne :)</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ vi /usr/local/bin/wifiup
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># On réveille la carte :</span>
</span></span><span style="display:flex;"><span>ifconfig iwn0 up
</span></span><span style="display:flex;"><span><span style="color:#776e71"># On scanne les réseaux pour trouver leur identifiant :</span>
</span></span><span style="display:flex;"><span>ifconfig iwn0 scan | grep -i nwid
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Choix du réseau :</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#48b685">&#34;A quel réseau se connecter ?&#34;</span>
</span></span><span style="display:flex;"><span>read _NWID
</span></span><span style="display:flex;"><span>echo <span style="color:#48b685">&#34;\nPhrase de passe ?&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Attention, la phrase de passe apparaît en clair l&#39;écran :</span>
</span></span><span style="display:flex;"><span>read _PASS
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Connexion au réseau utilisant une clé WPA (qui utilise encore du WEP ?) :</span>
</span></span><span style="display:flex;"><span>ifconfig iwn0 nwid <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$_NWID</span><span style="color:#48b685">&#34;</span> wpakey <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$_PASS</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Abtention d&#39;une adresse IP :</span>
</span></span><span style="display:flex;"><span>dhclient iwn0
</span></span></code></pre></div><p>Pour que ce script puisse être lancé en simple utilisateur, ajouter
l&rsquo;entrée suivante dans <code>/etc/doas.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">permit nopass $USER as root cmd /usr/local/bin/wifiup</span>
</span></span></code></pre></div><p><em>Bien entendu, changez &ldquo;$USER&rdquo; par votre login.</em></p>
<p>Pour lancer le script, il suffit de lancer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># /usr/local/bin/wifiup</span>
</span></span></code></pre></div><p><em>Et vite s&rsquo;en faire un alias pour plus de confort</em> ! :)</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour gérer le Wifi sous OpenBSD]]></summary>
        <published>2020-01-19T07:39:11+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9fb05996-0a18-1bdd-1b09-1186734f5e7b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-webcam/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Webcam / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Webcam" scheme="http://doc.huc.fr.eu.org/fr/tags/webcam/" />
        <category term="Audio" scheme="http://doc.huc.fr.eu.org/fr/tags/audio/" />
        <category term="Video" scheme="http://doc.huc.fr.eu.org/fr/tags/video/" />
        <content type="html"><![CDATA[<h2 id="activer-lenregistrement-vidéo">Activer l&rsquo;enregistrement vidéo</h2>
<p>En premier lieu, il vous faut activer la <a class="inside" href="/fr/sys/openbsd/tip-video/" title="Lien interne vers l&#39;article : 'Gérer la vidéo sous OpenBSD'">vidéo</a>
.</p>
<h2 id="vérifier-le-support">Vérifier le support</h2>
<p>Sous OpenBSD, la webcam est souvent identifiée par <code>/dev/video0</code>.</p>
<p>Afin de vérifier que votre webcam est reconnue, utilisez <code>usbdevs</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ usbdevs -v
</span></span><span style="display:flex;"><span>Controller /dev/usb0:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  port <span style="color:#f99b15">6</span> addr 4: high speed, power <span style="color:#f99b15">200</span> mA, config 1, Integrated Camera<span style="color:#5bc4bf">(</span>0xb221<span style="color:#5bc4bf">)</span>, Chicony Electronics Co., Ltd.<span style="color:#5bc4bf">(</span>0x04f2<span style="color:#5bc4bf">)</span>, rev 7.52
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Ou encore dmesg :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ dmesg | grep video0
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>uvideo0 at uhub3 port <span style="color:#f99b15">6</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Chicony Electronics Co., Ltd. Integrated Camera&#34;</span> rev 2.00/7.52 addr <span style="color:#f99b15">4</span>
</span></span></code></pre></div><h2 id="accès-à-la-webcam">Accès à la webcam</h2>
<p>Afin que le logiciel que vous préférez puisse accéder à la webcam sans
les droits administrateurs, il faut modifier les droits d&rsquo;écriture sur
<code>/dev/video0</code>.</p>
<p>Cela consiste à vous déclarer propriétaire de <code>/dev/video0</code> :</p>
<p><code>$ doas chown votre_nom_d_utilisateur /dev/video0</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Note : Si plusieurs utilisateurs utilisent l&rsquo;ordinateur, il faudra
insérer cette commande au lancement de la session. Si le gestionnaire de
connexion est <a class="inside" href="/fr/sys/openbsd/xenodm/" title="Lien interne vers l&#39;article : 'xenodm : Gestionnaire de sessions X pour OpenBSD'">xenodm</a>
, ça sera
dans le fichier <code>/etc/X11/xenodm/TakeConsole</code> ou <code>/etc/X11/xenodm/Xstartup</code>.</p>
<p>Désignez dans ce cas le nom d&rsquo;utilisateur avec <code>$USER</code>.</p>
</div>


<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>L&rsquo;astuce est de modifier votre fichier <code>.xsession</code>, tel que :</p>
<p><code>if [ -c /dev/video0 ]; then doas chown $USER /dev/video0; fi</code></p>
</div>

<h2 id="paramétrages">Paramétrages</h2>
<p>Le contrôle des paramètres de la webcam se fait avec la commande
<code>video(1)</code>, tel que :</p>
<p><code>$ video -c</code></p>
<p>Par exemple, le paramétrage de la luminosité ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>video <span style="color:#ef6155">brightness</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">200</span>
</span></span><span style="display:flex;"><span>brightness: <span style="color:#f99b15">128</span> -&gt; <span style="color:#f99b15">200</span>
</span></span></code></pre></div><hr>
<h2 id="exemples">Exemples</h2>
<h3 id="mpv">mpv</h3>
<p>Pour afficher en direct ce que votre caméra filme avec mpv :</p>
<p><code>$ mpv av://v4l2:/dev/video0</code></p>
<h3 id="fswebcam">fswebcam</h3>
<p>Lire la page <a class="inside" href="/fr/sys/openbsd/fswebcam/" title="Lien interne vers l&#39;article : 'fswebcam / OpenBSD'">fswebcam</a>
.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces de gestion de webcam sous OpenBSD]]></summary>
        <published>2020-01-19T07:29:50+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:fa34c0ca-bbae-bf41-f027-15fafb04300e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-usb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion des clés USB / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="USB" scheme="http://doc.huc.fr.eu.org/fr/tags/usb/" />
        <content type="html"><![CDATA[<h2 id="monter-automatiquement">Monter &ldquo;automatiquement&rdquo;</h2>
<p>Lisez notre page de configuration système : <strong>[[tutoriel:openbsd-mount-usb]]</strong></p>
<h2 id="monter-manuellement">Monter &ldquo;manuellement&rdquo;</h2>
<p>Merci de lire le chapitre notre page : [[tutoriel:openbsd-mount-usb#methode-manuelle]]</p>
<h2 id="formatage">Formatage</h2>
<p>Pour formater une clé USB, de même que tout type de disque dur, on
utilisera la commande <a href="https://man.openbsd.org/newfs.8" rel="external"><code>newfs</code>(8)</a>.</p>
<p>Les types de formats de fichiers suivants sont supportés :</p>
<ul>
<li>cd9660</li>
<li>ext2fs</li>
<li>ffs</li>
<li>mfs</li>
<li>msdos</li>
<li>nfs</li>
<li>ntfs</li>
<li>swap</li>
<li>tmpfs</li>
<li>udf</li>
<li>vnd</li>
</ul>
<p>Ce sont ceux pris en charge par <a href="https://man.openbsd.org/fstab.5" rel="external">fstab(5)</a>.</p>
<p>Il y a deux manières de s&rsquo;y prendre :</p>
<ul>
<li><code>newfs -t *type* device</code> où type est le type de format, parmi ceux sus-cités</li>
<li><code>newfs_*type* device</code></li>
</ul>
<p><code>newfs</code> est une commande suffisamment intelligente, qui lorsqu&rsquo;elle est
écrite avec l&rsquo;option <code>-t</code> redirige vers l&rsquo;équivalente de la seconde
écriture.</p>
<h3 id="exemple--fat32">Exemple : FAT32</h3>
<p>Après avoir utilisé <code>dmesg</code> pour identifier notre périphérique comme
expliqué ici, nous allons utiliser la commande <code>newfs_msdos</code> pour
formater une clé USB en FAT32 :</p>
<p>Admettons que la clé soit remontée en tant que <code>/dev/sd2</code> et qu&rsquo;une
partition soit présente dessus.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># newfs_msdos -F 32 /dev/rsd2a</span>
</span></span></code></pre></div><p>Une fois formatée, la partition apparaîtra en tant que <code>/dev/sd2i</code> et
pourra être montée et utilisée.</p>
<h2 id="norme-fidou2f">Norme FIDO/U2F</h2>
<p>Les clés USB de sécurité, à la norme FIDO/U2F, sont utilisables depuis
OpenBSD 6.7, grâce au pilote <a href="https://man.openbsd.org/fido.4" rel="external">fido(4)</a>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour gérer différents formats de clés USB sous OpenBSD]]></summary>
        <published>2020-01-19T07:20:03+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d19ae734-1c4c-a851-f551-2fd50084cdd7</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-python/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Python : Gestion de l&#39;environnement / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Python fait partie du système de base d&rsquo;OpenBSD.</p>
<h2 id="error-the-executable-homepython3-could-not-be-run-errno-13-permission-denied">ERROR: The executable $HOME/(&hellip;)/python3 could not be run: [Errno 13] Permission denied:</h2>
<p>Cette erreur est générée par le fait de la protection mémoire W^X !</p>
<p>Deux manières de résoudre le problème :</p>
<h3 id="modifications-système">Modifications système</h3>
<p>Pour remédier à la situation, nous allons modifier légèrement votre
<code>$HOME</code> et <code>/usr/local</code>, avec les droits administrateurs.</p>
<ul>
<li>Création des répertoires nécessaires dans <code>/usr/local</code>,</li>
<li>Attribution des droits utilisateurs nécessaires,</li>
<li>et, lien symbolique</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># mkdir -p /usr/local/${my_user}/python</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chown -R ${my_user}:wheel /usr/local/${my_user}</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ln -s /usr/local/${my_user}/python $home/python</span>
</span></span></code></pre></div><p>… où <code>${my_user}</code> représente votre identifiant utilisateur.</p>
<h4 id="pipenv">pipenv</h4>
<p>Pour l&rsquo;utilitaire <a href="https://docs.pipenv.org/en/latest/" rel="external"><code>pipenv</code></a>, il
faut modifier ceci aussi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ mkdir /usr/local/<span style="color:#ef6155">$USER</span>/python/virtualenvs
</span></span><span style="display:flex;"><span>$ ln -s /usr/local/<span style="color:#ef6155">$USER</span>/python/virtualenvs <span style="color:#ef6155">$HOME</span>/.local/share/virtualenvs
</span></span></code></pre></div><h3 id="option-wxallowed">Option wxallowed</h3>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Prenez conscience qu&rsquo;utiliser cette possibilité aura pour conséquence de
permettre l&rsquo;exécution de binaire potentiellement dangereux depuis votre
<code>$HOME</code>.</p>
<p><strong>Mieux vaut éviter</strong> !</p>
</div>

<p>Il est possible d&rsquo;ajouter l&rsquo;option de montage <code>wxallowed</code> à votre
partition $HOME si vous l&rsquo;avez créée.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour la gestion de l&#39;environnement de Python sous OpenBSD]]></summary>
        <published>2020-01-19T06:53:27+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:62917530-7387-aa59-80a6-5a4572e07102</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-themes/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Thèmes ; Polices ; Émoticônes / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Themes" scheme="http://doc.huc.fr.eu.org/fr/tags/themes/" />
        <content type="html"><![CDATA[<h2 id="installer-polices-et-émojis">Installer polices et émojis</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># for file in $(pkg_info -Q fonts | grep -v installed); do pkg_add $file; done</span>
</span></span></code></pre></div><h2 id="installer-thèmes-dicônes">Installer thèmes d&rsquo;icônes</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># for file in $(pkg_info -Q icon-theme | grep -v installed); do pkg_add $file; done</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce de gestion de thèmes sous OpenBSD]]></summary>
        <published>2020-01-19T06:37:13+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c7b6ea5b-424a-89b3-0786-8631c12471c0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/pf/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF : Packet Filter</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Network" scheme="http://doc.huc.fr.eu.org/fr/tags/network/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="packet-filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="parefeu" scheme="http://doc.huc.fr.eu.org/fr/tags/parefeu/" />
        <content type="html"><![CDATA[<h2 id="pf--packet-filter">PF : Packet Filter</h2>
<p>Cette documentation traitera de l&rsquo;usage du gestionnaire de filtrage
&ldquo;pare-feu&rdquo; nommé <strong>PF</strong>…</p>
<p>L&rsquo;outil <code>pfctl</code> permet de <strong>contrôler l&rsquo;état du parefeu</strong>.</p>
<p>Le fichier <code>/etc/pf.conf</code> permet de <strong>gérer la configuration</strong></p>
<h2 id="installation">Installation</h2>
<p>Par défaut, rien à installer par soi-même… il est inclus de base.</p>
<p>Depuis la version 4.6 d&rsquo;OpenBSD, il n&rsquo;est plus nécessaire de l&rsquo;activer,
puisqu&rsquo;il l&rsquo;est par défaut.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Cette section traite de l&rsquo;usage de l&rsquo;outil <code>pfctl</code> :</p>
<p><em><strong>Note</strong> : L&rsquo;usage de l&rsquo;outil <code>pfctl</code> nécessite des droits administrateur…
pensez-y !</em></p>
<p>Quelques informations à-propos des options de pfctl :</p>
<ul>
<li>l&rsquo;option <code>-d</code> : arrête le parefeu</li>
<li>l&rsquo;option <code>-e</code> : activer, vérifier l&rsquo;état de pf</li>
<li>l&rsquo;option <code>-ef</code> : activer le parefeu tout en ciblant le fichier de
configuration, tel que : <code>-ef /etc/pf.conf</code></li>
<li>l&rsquo;option <code>-f</code> : permet de recharger les nouvelles règles à partir du fichier.</li>
<li>l&rsquo;option <code>-F</code> : permet de vider toutes les règles et autres tables du parefeu</li>
<li>l&rsquo;option <code>-nf</code> : permet de vérifier les règles écrites dans un fichier,
sans les charger.</li>
<li>l&rsquo;option <code>-r</code> : permet de faire du <strong>reverse dns</strong></li>
<li>l&rsquo;option <code>-s</code> : afficher les informations d&rsquo;état…
<em>voir plus bas, pour plus d&rsquo;infos.</em></li>
<li>l&rsquo;option <code>-t</code> : spécifie une action précise sur une table particulière,
tel que : <code>-t &lt;table_nom&gt; -T command adr_ip</code></li>
<li>l&rsquo;option <code>-v</code> : est le mode verbeux</li>
</ul>
<p><em>De plus amples informations dans le <a href="http://man.openbsd.org/OpenBSD-current/man8/pfctl.8" rel="external">manpage</a>
correspondant !</em></p>
<h2 id="configuration">Configuration</h2>
<p>Le <strong>fichier de configuration principal</strong> du pare-feu <strong>PF</strong> se nomme :
<code>/etc/pf.conf</code></p>
<p>Il est possible de créer des sous-fichiers de configuration qui seront
appelés par la directive : <br>
<code>include /etc/pf/filename.conf</code></p>
<p>Le fichier de configuration est décomposé en plusieurs sections :</p>
<ul>
<li>déclarations de listes, macros, tables - de préférence - absolument en premier</li>
<li>gestion de la bande passante - au besoin, en suivant</li>
<li>déclaration des règles bloquantes, et/ou filtrantes - absolument en dernier</li>
</ul>
<p><em>De plus amples informations dans le <a href="http://man.openbsd.org/pf.conf.5" rel="external">manpage</a>
correspondant !</em></p>
<h3 id="gestion-des-listes">Gestion des listes</h3>
<p>Les listes définissent des critères multiples similaires, tels que les
noms de ports, des numéros de protocoles, plusieurs adresses IP, etc.</p>
<p>Les listes sont définies en spécifiant les items par l&rsquo;usage des crochets
{ }, chaque item pouvant être séparé soit par un espace, soit par une
virgule.</p>
<p><code>block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any</code></p>
<p>Une liste peut contenir une autre liste imbriquée.</p>
<p>Là où les listes se trouvent limiter en usage, les macros prennent
facilement le relais</p>
<h3 id="gestion-des-macros">Gestion des macros</h3>
<p>Les macros sont l&rsquo;équivalent de variables dans les langages informatiques.</p>
<p>Elles définissent une valeur ou un ensemble de valeurs… celles-ci peuvent
être une ou plusieurs interfaces réseaux, une ou plusieurs adresses ip,
un ou plusieurs numéros de ports, etc… <br>
voire une partie d&rsquo;écriture de règles.</p>
<p>Les macros peuvent contenir des listes, d&rsquo;autres macros.</p>
<p>⇒ Définition :</p>
<ul>
<li>Les noms de ces macros doivent ABSOLUMENT commencer par une lettre,
un chiffre ou le symbole <code>_</code>.</li>
<li>Il est interdit d&rsquo;utiliser des mots réservés, tels que :
<code>pass</code>, <code>in</code>, <code>out</code>…</li>
</ul>
<p>Ces macros, une fois définies, sont utilisées dans le contexte des règles.</p>
<p>⇒ Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">iface</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;em0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">http_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 80 443 }&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pre</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass in quick on ep0 inet proto tcp from &#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">post</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;to any port { 80, 6667 }&#34;</span>
</span></span></code></pre></div><p><em>Pour plus d&rsquo;informations, lire</em> : <a href="https://www.openbsd.org/faq/pf/shortcuts.html#macros" rel="external">https://www.openbsd.org/faq/pf/shortcuts.html#macros</a></p>
<h3 id="gestion-des-tables">Gestion des tables</h3>
<p>Les tables sont une collection d&rsquo;adresses et/ou de réseaux.</p>
<p>C&rsquo;est une manière très efficace et puissante de gérer un ensemble
d&rsquo;informations, consommant moins de ressources processeur et mémoire.</p>
<p>À privilégier, plutôt qu&rsquo;une liste de macros, dès que vous voulez gérer
un ensemble d&rsquo;adresses ip !</p>
<p>⇒ Définition :</p>
<ul>
<li>Tout comme pour les macros, les noms réservés ne DOIVENT pas être utilisés !</li>
<li>Une table initialisée avec une liste vide <code>{ }</code> sera purgée, lors du chargement…</li>
<li>Elles peuvent être définies en étant suivies d&rsquo;un de ces trois attributs :
<code>const</code>, <code>counters</code>, ou <code>persist</code></li>
</ul>
<p>⇒ Drapeaux :</p>
<ul>
<li><code>const</code> : empêche que la table soit ultérieurement altérée, une fois chargée.</li>
<li><code>counter</code> : active le compte des bits et autres paquets par adresse ip.</li>
<li><code>persist</code> : force le noyau à garder la table, même si aucune règle se
réfère à elle. Ce drapeau permet l&rsquo;ajout ultérieur d&rsquo;informations…</li>
</ul>
<p>⇒ Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">iface</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;axe0&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;private&gt; const { 10/8, 172.16/12, 192.168/16 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;badips&gt; persist</span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block on $iface from { &lt;private&gt;, &lt;badips&gt; } to any</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pfctl -t badips -T add 204.92.77.111</span>
</span></span></code></pre></div><p><strong>Note</strong> : Une table peut être gérée par un ou plusieurs fichiers, qui
seront une liste d&rsquo;adresses ip ou de noms de machines. Une ligne commençant
par le symbole dièse &lsquo;#&rsquo; est considérée comme un commentaire et sera ignorée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;spam&gt; persist file &#34;/dir/filename1&#34; </span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block on fxp0 from &lt;spam&gt; to any</span>
</span></span></code></pre></div><h3 id="gestion-des-ancres">Gestion des ancres</h3>
<p>Les ancres sont un ensemble de règles, qui peuvent être manipulées de
manière dynamique.</p>
<p>Elles sont au jeu de règles, ce que les tables sont à la gestion dynamique
des adresses ip ou réseaux.</p>
<p>Une ancre est une collection de règles… de tables… voire même d&rsquo;ancres.</p>
<p><strong>Attention</strong> : Pour nommer une ancre, <strong>veillez à ne pas utiliser un nom
déjà défini auparavant</strong>, même s&rsquo;il définit une table. L&rsquo;outil <code>pfctl</code>
vous avertira, sinon, d&rsquo;une collision de noms dans l&rsquo;espace global de noms…
à juste titre !</p>
<p>⇒ Utilisation :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">anchor nom_ancre {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">jeu de règles</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>L&rsquo;ajout dynamique à la main peut se faire ainsi :</p>
<p><code># echo &quot;pass in proto tcp from 192.0.2.3 to any port 22&quot; | pfctl -a nom_ancre -f -</code></p>
<p>Elles peuvent aussi être écrite dans un fichier, qui aura soit un jeu de
règles définies, et/ou pourra être géré dynamiquement, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">ancre nom_ancre</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">load nom_ancre from &#34;/etc/pf/fichier_ancre&#34;</span>
</span></span></code></pre></div><p><em>Pour de plus amples informations, lire</em> : <a href="https://www.openbsd.org/faq/pf/anchors.html" rel="external">https://www.openbsd.org/faq/pf/anchors.html</a></p>
<h3 id="gestion-de-la-bande-passante">Gestion de la bande passante</h3>
<p>Les paquets peuvent être assignés à une ou plusieurs queues, afin de
gérer la bande passante.</p>
<p>Il faut définir au moins une queue pour la configurer, et ensuite créer
des règles qui feront référence à la queue par son nom. Si une queue
appelée n&rsquo;existe pas pour une interface réseau, c&rsquo;est la queue par défaut
qui sera utilisée.</p>
<p><strong>Il DOIT</strong> y avoir une queue maître, qui fait référence spécifiquement
à une interface réseau. Les autres queues, appelées <em>enfants</em>, sont
créées relativement à la queue <em>maître</em>.</p>
<p>⇒ Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">iface</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;em0&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue rq on $iface bandwidth 100M </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue ssh parent rq bandwidth 10M</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue http parent rq bandwidth 80M</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue std parent rq bandwidth 10M default </span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block return out on $iface inet all set queue std </span>
</span></span></code></pre></div><p>⇒ Définition des mots clés réservés :</p>
<ul>
<li><code>default</code> : spécifie la queue par défaut</li>
<li><code>on</code> : spécifie une interface réseau</li>
<li><code>parent</code> : attache une queue à une queue maître</li>
<li><code>qlimit</code> : définit le nombre maximum de paquets capturés dans une queue.
<em>Par défault : 50</em></li>
</ul>
<p>⇒ Définition de valeurs de bande passante :</p>
<p>Les valeurs de bande passante <strong>DOIVENT</strong> absolument être des entiers ;
ces valeurs peuvent être suffixées des lettres suivantes <code>K</code>, <code>M</code>, ou <code>G</code>,
qui respectivement représentent le nombre de bits par secondes gérés,
tels que Kilobits, Megabits, ou Gigabits.</p>
<p>Ces valeurs ne doivent pas dépasser la taille de la bande passante allouée
à une interface réseau !</p>
<p>⇒ Attributs possibles :</p>
<ul>
<li><code>max</code> : spécifie la limite maximale de bande passante allouée à une queue</li>
<li><code>min</code> : cible la taille minimale, réservée, de bande passante à une queue
donnée</li>
<li><code>burst</code> : est un attribut qui permet à une bande passante d&rsquo;être outrepassée
dans un laps de temps donnée, pour une queue précise</li>
</ul>
<p>⇒ Exemples :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">queue ssh parent std bandwidth 10M, min 5M, max 25M</span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue ssh parent std bandwidth 10M burst 90M for 100ms</span>
</span></span></code></pre></div><h3 id="gestion-des-règles">Gestion des règles</h3>
<p>La première des règles la plus basique, et sécuritaire est celle de tout
bloquer :</p>
<p><code>block</code></p>
<h2 id="règles-de-syntaxe">Règles de syntaxe</h2>
<p>Il existe des règles de grammaire et de simplifications d&rsquo;écriture des
règles PF.</p>
<h3 id="règles-block">Règles &ldquo;block&rdquo;</h3>
<p>⇒ Cela ne sert à rien d&rsquo;écrire ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>  <span style="color:#06b6ef">block in all</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">block out all</span>
</span></span></code></pre></div><p>Ni :</p>
<p><code>block all</code></p>
<p><strong>Écrire</strong> <code>block</code> <strong>suffit !</strong></p>
<hr>
<p>⇒ De même, il ne sert à rien de spécifier :</p>
<p><code>block drop</code></p>
<p>ou :</p>
<p><code>block return</code></p>
<p>⇒ Sauf à utiliser ces mots-clés, dans le contexte de certaines règles PF,
<strong>spécifier la politique de rejet, puis</strong> utiliser juste le mot clé <strong>block</strong>,
tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">set block-policy return</span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block</span>
</span></span></code></pre></div><h3 id="autres-règles">Autres règles</h3>
<p>L&rsquo;usage du mot clé reservé <code>all</code> ou de l&rsquo;expression réservé <code>from any to any</code>
<strong>ne servent à rien</strong> non plus. Ce sont des règles implicites, par défaut !</p>
<p><em>Pour plus d&rsquo;informations, lire</em> : <a href="https://www.openbsd.org/faq/pf/shortcuts.html#grammar" rel="external">https://www.openbsd.org/faq/pf/shortcuts.html#grammar</a></p>
<h2 id="recommandations">Recommandations</h2>
<h3 id="suivi-de-connexions">Suivi de connexions</h3>
<p>Le mot clé <code>keep state</code> permet de gérer le suivi de connexion des flux
sur les protocoles TCP, UDP et/ou ICMP. Ce mot clé permet de gérer les
messages ICMP relatifs à la régulation du trafic, tel que les messages
&ldquo;source quench&rdquo;, de fait il n&rsquo;y a pas besoin de créer de règles spécifiques.</p>
<h3 id="tcp">TCP</h3>
<p>Pour s&rsquo;assurer de n&rsquo;autoriser QUE les nouvelles connexions, ou plutôt
l&rsquo;initiation de nouvelles connexions, on utilisera seulement les drapeaux
<code>S/SA</code> - SYN sans ACK -… le suivi de connexion gérera le reste correctement.</p>
<p>⇒ Exemple :</p>
<p><code>pass in on em0 proto tcp flags S/SA keep state</code></p>
<p><strong>Note</strong> : c&rsquo;est une bonne habitude à prendre de gérer l&rsquo;état de connexion
à partir de nouvelles initialisation !</p>
<p><em>Veuillez lire la page de la <a href="https://www.openbsd.org/faq/pf/filter.html" rel="external">FAQ Filter</a>
pour mieux comprendre ce qu&rsquo;est la notion de suivi d&rsquo;états, la syntaxe
des règles PF à-propos des états, les différentes options possibles, etc…</em></p>
<h3 id="informations-détats">Informations d&rsquo;états</h3>
<p>Ainsi que vu plus haut, en début de page, c&rsquo;est l&rsquo;option <code>-s</code> qui permet
d&rsquo;obtenir différentes informations relatives aux états du pare-feu.
Cette option utilise des drapeaux pour afficher différemment les informations.</p>
<p><code># pfctl -s flag</code></p>
<p>⇒ Définition des drapeaux :</p>
<ul>
<li>
<p>Voir toutes les informations : <code>-sa</code></p>
<ul>
<li><em>ne pas confondre avec l&rsquo;option
pour voir les ancres !</em></li>
</ul>
</li>
<li>
<p><code>info</code> : affiche les statistiques globales</p>
<ul>
<li><em>version abrégée : <code>-si</code></em></li>
</ul>
</li>
<li>
<p><code>nat</code> : affiche les informations de traduction d&rsquo;adresses réseaux, de
type <code>nat</code>, et <code>rdr</code>.</p>
</li>
<li>
<p><code>rules</code> : affiche les règles de filtrage chargées en mémoire - un peu,
l&rsquo;équivalent des options &lsquo;-Lnv&rsquo; à iptables</p>
<ul>
<li><em>version abrégée : <code>-sr</code></em></li>
</ul>
</li>
<li>
<p><code>state</code> : affiche l&rsquo;état des connexions ouvertes.</p>
<ul>
<li><em>version abrégée : <code>-ss</code></em></li>
</ul>
</li>
<li>
<p>Anchor : option <code>-s Anchor</code>, avec ou sans un &rsquo;s&rsquo; final, permet de connaître
le nom des tables utilisées. <em>Les ancres peuvent aussi être gérées en
utilisant directement l&rsquo;option <code>-sa</code>, ainsi que l&rsquo;ajout d&rsquo;un de ses
drapeaux <code>-f</code>, <code>-F</code>, ou <code>-s</code></em>…</p>
</li>
<li>
<p>Label : option <code>-s label</code>, avec ou sans un &rsquo;s&rsquo; final, permet d&rsquo;obtenir
les informations liées à des labels.</p>
<ul>
<li><em>version abrégée : <code>-sl</code></em></li>
</ul>
</li>
<li>
<p>Queue : option <code>-s queue</code></p>
<ul>
<li><em>version abrégée : <code>-sA</code></em> - avec un A majuscule ;</li>
<li>à ne pas confondre avec les ancres !</li>
</ul>
</li>
<li>
<p>Table : option <code>-s Tables</code>, avec ou sans un &rsquo;s&rsquo; final, permet de connaître
le nom des tables utilisées. <em>Si une table est gérée par une ancre,
il est possible de la contrôler en appelant d&rsquo;abord l&rsquo;ancre puis la
table, telle que :<br>
<code>pfctl -a ancre -t table -T command</code></em>…</p>
<ul>
<li><em>version abrégée : <code>-sT</code></em></li>
</ul>
</li>
</ul>
<p><strong>Note</strong> : Pensez à utiliser l&rsquo;option <code>-vs</code>, voire <code>-vvs</code> qui permet
d&rsquo;avoir un état plus complet de l&rsquo;information recherchée, si celui est
possible.</p>
<p><em>Pour de plus amples informations, veuillez lire le manpage correspondant
à l&rsquo;outil &lsquo;pfctl&rsquo;</em>…</p>
<h2 id="pf--nombre-maximum-détats">PF : Nombre maximum d&rsquo;états</h2>
<p>Par défaut, PF gère un nombre maximal d&rsquo;entrées dans sa table d&rsquo;états
qui est de 10 000.</p>
<p>Pour connaître le nombre d&rsquo;entrées dans la table d&rsquo;états, en cours : <br>
<code># pfctl -ss | wc -l</code></p>
<p>Si et seulement si vous êtes proche de cette limite, vous pouvez agrandir
le nombre d&rsquo;entrées dans la table, en paramétrant votre fichier <code>/etc/pf.conf</code>,
tel que : <br>
<code>set limit states 20000</code></p>
<h2 id="exemples">Exemples</h2>
<p>Ci-dessous, retrouvez un exemple basique de règles PF qui sont donnés
pour le flux sur ipv4. <br>
Il faudra faire les modifications nécessaires pour ipv6 ;)</p>
<h3 id="pf-pour-station">PF pour station</h3>
<h4 id="version-minimale">Version minimale</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">block</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out all keep state</span>
</span></span></code></pre></div><p>Ces deux règles &ldquo;disent&rdquo; :</p>
<ul>
<li>refusent tout le trafic entrant</li>
<li>accepte le trafic sortant et relatif aux connexions.</li>
</ul>
<h4 id="version-améliorée">Version améliorée</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See pf.conf(5) and /etc/examples/pf.conf</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_bogons&gt; persist file &#34;/etc/pf_table_bogons&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set block-policy return</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set optimization normal</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set reassemble yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set ruleset-optimization none</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set skip on lo</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">antispoof for egress</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match in all scrub (max-mss 1440 no-df random-id reassemble tcp)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop in quick on egress from { &lt;t_bogons&gt; } to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop out quick on egress from any to { &lt;t_bogons&gt; }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># By default, do not permit remote connections to X11</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in on ! lo0 proto tcp to port 6000:6010</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Prevent dns leaks : best to use with unbound, dnscrypt-proxy</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in log on egress inet proto { tcp udp } from any to ! egress port 53</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block           # block stateless traffic</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass            # establish keep-state</span>
</span></span></code></pre></div><p>⇒ Quelques petites explications :</p>
<ul>
<li><code>egress</code> est un nom définissant toute(s) le(s) interface(s) réseau(x)
correspondant à la ou le(s) route(s) par défaut, vers la ou le(s)
passerelles. La règle <code>antispoof</code> est une mesure de protection dite
&rsquo;no spoofing&rsquo;, afin que ne soit possible de lui &ldquo;piquer&rdquo; son ou ses
adresses réseau(x).</li>
<li>on charge une table contenant les segments réseaux appelés BOGON ne
devant pas se trouver sur le net. Est supprimé tout trafic correspondant,
sans aucun état d&rsquo;âme, en entrée et en sortie.
Le fichier <code>/etc/pf_table_bogons</code> est donné en exemple ci-dessous !</li>
</ul>
<h3 id="pf-pour-serveur">PF pour serveur</h3>
<p>Les deux versions basiques de règles PF sont exactement les mêmes - la
deuxième utilise plus profondément les listes  et macros pour ne pas avoir
à réécrire certaines portions !</p>
<h4 id="version-normale">Version normale</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See pf.conf(5) and /etc/examples/pf.conf</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># lists, macros</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_tcp_ports</span> <span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{ http ftp whois }&#34; # ajouter imap, smtp, rsync ou autres flux TCP nécessaires en sortie</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_tcps_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ https }&#34; # ajouter imaps, smtps ou autres flux TCP &#34;secure&#34; nécessaires en sortie</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_udp_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ domain }&#34; # ajouter tout flux UDP nécessaire en sortie</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">web_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ http https }&#34; # modifier entrée services web</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_bogons&gt; persist file &#34;/etc/pf_table_bogons&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_abuse_ssh&gt; persist</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_abuse_web&gt; persist</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set block-policy return</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set optimization normal</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set reassemble yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set ruleset-optimization none</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set skip on lo</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">antispoof for lo</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">antispoof for egress</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#scrub in all fragment reassemble no-df max-mss 1440 &lt;= old version; do not using-it!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match in all scrub (max-mss 1440 no-df random-id reassemble tcp)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Prevent dns leaks : best to use with unbound, dnscrypt-proxy</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in log on egress inet proto { tcp udp } from any to ! egress port 53</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop in quick on egress from { &lt;t_bogons&gt; } to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop out quick on egress from any to { &lt;t_bogons&gt; }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># block abuses</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in log quick proto tcp from &lt;t_abuse_ssh&gt; to any port ssh</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in log quick proto tcp from &lt;t_abuse_web&gt; to any port $web_ports</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block           # block stateless traffic</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass few udp ports</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass quick inet proto icmp all icmp-type { echoreq, unreach }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to egress port mdns allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass in</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto tcp to any port ssh flags S/SA modulate state (max-src-conn-rate 3/60, overload &lt;t_abuse_ssh&gt; flush global)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto tcp to any port $web_ports flags S/SA modulate state (max-src-conn 100, max-src-conn-rate 40/5, overload &lt;t_abuse_web&gt; flush global)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out log on egress proto tcp to any port $auth_tcp_ports modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out log on egress proto tcp to any port $auth_tcps_ports modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress proto udp to any port $auth_udp_ports allow-opts keep state</span>
</span></span></code></pre></div><h4 id="version-améliorée-1">Version améliorée</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See pf.conf(5) and /etc/examples/pf.conf</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># lists, macros</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_tcp_ports</span> <span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{ http ftp whois }&#34; # ajouter imap, smtp, rsync ou autres flux TCP nécessaires en sortie</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_tcps_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ https }&#34; # ajouter imaps, smtps ou autres flux TCP &#34;secure&#34; nécessaires en sortie</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auth_udp_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ domain ntp mdns }&#34; # ajouter tout flux UDP nécessaire en sortie</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ports</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">web_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ http https }&#34; # modifier entrée services web</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># statefull tracking options - sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ssh_sto</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;(max-src-conn-rate 3/60, overload &lt;t_abuse_ssh&gt; flush global)&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">web_sto</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;(max-src-conn 100, max-src-conn-rate 40/5, overload &lt;t_abuse_web&gt; flush global)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">flag_syn</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;flags S/SA modulate state&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># others</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">edropin</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block drop in quick on egress from&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">edropout</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block drop out quick on egress from&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">epassout</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass out log on egress proto tcp to any port&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inblocktcp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block in log quick proto tcp from&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inpasstcp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass in on egress proto tcp to any port&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_bogons&gt; persist file &#34;/etc/pf_table_bogons&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_abuse_ssh&gt; persist</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_abuse_web&gt; persist</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set block-policy return</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set optimization normal</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set reassemble yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set ruleset-optimization none</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set skip on lo</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">antispoof for { lo, egress }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#scrub in all fragment reassemble no-df max-mss 1440 &lt;= old version; do not using-it!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match in all scrub (max-mss 1440 no-df random-id reassemble tcp)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Prevent dns leaks : best to use with unbound, dnscrypt-proxy</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block in log on egress inet proto { tcp udp } from any to ! egress port 53</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$edropin { &lt;t_bogons&gt; } to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$edropout any to { &lt;t_bogons&gt; }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># block abuses</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inblocktcp &lt;t_abuse_ssh&gt; to any port ssh</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inblocktcp &lt;t_abuse_web&gt; to any port $web_ports</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block           # block stateless traffic</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass few udp ports</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass quick inet proto icmp all icmp-type { echoreq, unreach }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to egress port mdns allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass in</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpasstcp ssh $flag_syn $ssh_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpasstcp $web_ports $flag_syn $web_sto</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pass out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$epassout $auth_tcp_ports $flag_syn</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$epassout $auth_tcps_ports $flag_syn</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress proto udp to any port $auth_udp_ports allow-opts</span>
</span></span></code></pre></div><h3 id="table-bogons">table bogons</h3>
<p>Ces adresses ne doivent <strong>en aucun cas se retrouver sur Internet</strong> -
<em>malheureusement de petits malins les utilisent, d&rsquo;où la raison de les filtrer !</em></p>
<p>Le fichier <code>/etc/pf_table_bogons</code> doit contenir des adresses CIDR,
telles que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">0.0.0.0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">10.0.0.0/8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">100.64.0.0/10</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">127.0.0.0/8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">128.0.0.0/16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">169.254.0.0/16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">172.16.0.0/12</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">191.255.0.0/16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">192.0.0.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">192.0.2.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">192.88.99.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#192.168.0.0/16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">198.18.0.0/15</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">198.51.100.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">203.0.113.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">223.255.255.0/24</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">224.0.0.0/4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">240.0.0.0/4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">255.255.255.255</span>
</span></span></code></pre></div><p>⇒ Pour information :</p>
<ul>
<li><code>10.0.0.0/8</code> # private network ( RFC 1918 )</li>
<li><code>100.64.0.0/10</code> # cf RFC 6598</li>
<li><code>127.0.0.0/8</code>, <code>128.0.0.0/16</code>   # Loopback ( RFC 1122 ),
IANA reservations ( RFC 3330 )</li>
<li><code>169.254.0.0/16</code>, <code>172.16.0.0/12</code>    # Link Local Block ( RFC 3927 ),
private network ( RFC 1918 )</li>
<li><code>191.255.0.0/16</code>, <code>192.0.0.0/24</code>, <code>192.0.2.0/24</code>, <code>192.88.99.0/24</code> # ?,
IETF Protocol 5 ( RFC 5736 ), Test-Net 1 ( RFC 1166 ), 6to4 Relay Anycast ( RFC 3068 )</li>
<li><code>192.168.0.0/16</code>    # privates classes networks ( RFC 1918 )
&lt;= à commenter pour pouvoir &ldquo;contacter&rdquo; stations/serveurs locaux</li>
<li><code>198.18.0.0/15</code>, <code>198.51.100.0/24</code>   # Network Interconnect Device
Benchmark Testing ( RFC 2544 ), Test-Net 2 ( RFC 5737 )</li>
<li><code>203.0.113.0/24</code>, <code>223.255.255.0/24</code>, <code>224.0.0.0/4</code>, <code>240.0.0.0/4</code> # Test-Net 3
( RFC 5737 ), ?,  Class D Reserved ( RFC 3171 ), Class E Reserved ( RFC 1112 ),…</li>
<li><code>255.255.255.255</code>   # limited broadcast destination address</li>
</ul>
<hr>
<p><strong>Note</strong> : Le site <a href="https://www.team-cymru.org/bogon-reference.html" rel="external">Team Cymru</a>
met à jour une <a href="https://www.team-cymru.org/Services/Bogons/bogon-bn-agg.txt" rel="external">liste</a> +
ou - régulière des adresses dites &ldquo;bogons&rdquo;…</p>
<ul>
<li>pour <a href="https://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt" rel="external">IPv4</a></li>
<li>et <a href="https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt" rel="external">IPv6</a></li>
</ul>
<h3 id="table-badips">Table badips</h3>
<p>De même que la table gérant les réseaux bogons, il est possible d&rsquo;utiliser
des listes sur internet pour filtrer des adresses IP et/ou des segments
entiers de réseaux, qui sont reconnus par plusieurs entités, elles-mêmes
reconnues officiellement ou non, pour aider à lutter contre.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_badips&gt; persist file &#34;/dir/badips_ipv4&#34; counters</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_badips6&gt; persist file &#34;/dir/badips_ipv6&#34; counters</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop in quick on egress from { &lt;t_badips&gt; } to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop out quick on egress from any to { &lt;t_badips&gt; }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop in quick on egress inet6 from { &lt;t_badips6&gt; } to any</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop out quick on egress inet6 from any to { &lt;t_badips6&gt; }</span>
</span></span></code></pre></div><h2 id="astuces">Astuces</h2>
<p>Les astuces concernant ICMP, ICMPv6, et Traceroute sont tirées du livre
&ldquo;The Book of PF&rdquo; !</p>
<p>Retrouvez une &ldquo;<a href="https://gist.github.com/tracphil/4353170" rel="external">cheat sheet</a>&quot;…</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>ATTENTION : Les astuces ci-dessous ne sont que des exemples .<br>
Il est de votre devoir de les adapter, en ayant bien compris les principes
de gestion de PF !</p>
<p>Elles pourraient probablement ne pas fonctionner ou ne pas restituer le
résultat attendu, surtout si vous ne savez pas les adapter à vos besoins !</p>
</div>

<h3 id="icmp-icmpv6">ICMP, ICMPv6</h3>
<pre tabindex="0"><code class="language-vfg" data-lang="vfg"># macros
icmp_types=&#34;{ echoreq unreach }&#34;
icmp6_types=&#34;{ unreach toobig timex paramprob echoreq routeradv neighbrsol neighbradv }&#34;
(…)
# icmp (pass in+out)
pass quick inet proto icmp icmp-type $icmp_types
pass quick inet6 proto icmp6 icmp6-type $icmp6_types
</code></pre><p><em><strong>Note</strong> : N&rsquo;hésitez pas à lire les manpages <a href="http://man.openbsd.org/OpenBSD-current/man4/icmp.4" rel="external">icmp(4)</a>
et <a href="http://man.openbsd.org/OpenBSD-current/man4/icmp6.4" rel="external">icmp6(4)</a></em></p>
<h3 id="avahi-mdns-ssdp">Avahi (mDNS, SSDP)</h3>
<p>Voici des règles IPv4 et IPv6 pour le trafic multicast et SSDP liés à la
bibliothèque Avahi !</p>
<p>⇒ pour le trafic mDNS :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 224.0.0.251 port mdns allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to ff02::fb port mdns allow-opts </span>
</span></span></code></pre></div><p>⇒ pour le trafic SSDP :</p>
<ul>
<li>pour IPv6 :
<ul>
<li>&lsquo;&lsquo;ff02::c&rsquo;&rsquo; est l&rsquo;adresse multicast de lien local</li>
<li>&lsquo;&lsquo;ff05::c&rsquo;&rsquo; est l&rsquo;adresse multicast de site local</li>
<li>&lsquo;&lsquo;ff08::c&rsquo;&rsquo; est l&rsquo;adresse multicast d&rsquo;organisation local</li>
<li>il existe aussi &lsquo;&lsquo;ff0e::c&rsquo;&rsquo; pour l&rsquo;adresse multicast global - <em>que
nous n&rsquo;utiliserons pas dans le contexte local</em> !</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass proto udp from any to 239.255.255.250 port ssdp allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass inet6 proto udp from any to { ff02::c, ff05::c, ff08::c } port ssdp allow-opts </span>
</span></span></code></pre></div><h3 id="multiports">multiports</h3>
<p>Exemple pour du flux torrent : <code>6881:6891</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress inet proto tcp from any to 192.168.0.3 port 6881:6891 flags S/SA</span>
</span></span></code></pre></div><h3 id="samba">samba</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">smb_ports_tcp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 135 137 139 445 }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">smb_ports_udp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 135 137 138 445 }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># samba in</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto tcp from egress:network to egress port $smb_ports_tcp flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto udp from egress:network to egress port $smb_ports_udp allow-opts keep state</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># samba out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress proto tcp from egress to egress:network port $smb_ports_tcp flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress proto udp from egress to egress:network port $smb_ports_udp allow-opts keep state</span>
</span></span></code></pre></div><h3 id="syncthing">syncthing</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># syncthing in</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress inet proto tcp from { 192.168.1.0/24 } to egress port 22000 flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress inet proto udp from { 192.168.1.0/24 } to egress port 21027</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># syncthing out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet proto tcp from egress to { 192.168.1.0/24 } port 22000 flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet proto udp from egress to { 192.168.1.0/24 } port 21027</span>
</span></span></code></pre></div><h3 id="traceroute">Traceroute</h3>
<p>Il n&rsquo;est pas forcément nécessaire de créer des règles pour utiliser
l&rsquo;outil traceroute, en effet l&rsquo;option <code>-I</code> permet de l&rsquo;utiliser en ciblant
UDP. Néanmoins, si vous souhaitez obtenir le comportement par défaut, il
faut utiliser les règles suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress inet proto udp to port 33433:33626 # For IPv4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress inet6 proto udp to port 33433:33626 # For IPv6</span>
</span></span></code></pre></div><p><em><strong>Note</strong> : N&rsquo;hésitez pas à lire le manpage <a href="http://man.openbsd.org/OpenBSD-current/man8/traceroute.8" rel="external">traceroute(8)</a></em></p>
<h3 id="personnalisation-shell">Personnalisation Shell</h3>
<p>Rajoutez dans votre fichier <code>~/.kshrc</code>, les alias suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_clean_all</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -F all&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_clean_counters</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -z&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_clean_info</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -F info&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_clean_queue</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -F queue&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_clean_rules</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -F rules&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_edit</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas nano /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_info</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -si&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_info_tables</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -vvsT&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_less</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -vf /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_load_table</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -T load -f /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_reload</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -f /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_restart</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -d &amp;&amp; doas pfctl -ef /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_start</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -ef /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_stop</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -d&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_test</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -nf /etc/pf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_view</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -sr&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_view_tables</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pfctl -sT&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pf_watch</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas tcpdump -n -e -ttt -i pflog0&#34;</span>
</span></span></code></pre></div><p>Exécutez à nouveau : <code>. .kshrc</code></p>
<p>Maintenant, vous pourrez vous faciliter la vie, en exécutant un des
alias, commençant par <code>pf_*</code> ;-)</p>
<hr>
<h2 id="informations-avancées">Informations avancées</h2>
<h3 id="icmp-icmpv6-1">ICMP, ICMPv6</h3>
<p><strong>ATTENTION</strong> : les recommandations de l&rsquo;IETF - <strong>Internet Engineering Task Force</strong> -,
voire de l&rsquo;IANA - <strong>Internet Assigned Numbers Authority</strong> - sont de supprimer :
<code>drop</code> - impérativement les codes suivants :</p>
<p>⇒ ICMP :</p>
<ul>
<li>3/6 - Destination Network Unknown</li>
<li>3/8 - Source Host Isolated</li>
<li>4/0 - Source Quench &lt;= voire de journaliser !</li>
<li>15/0 - Information Request Message</li>
<li>16/0 - Information Reply Message</li>
</ul>
<p>⇒ ICMP v6 :</p>
<ul>
<li>le code 137 - Redirect Message</li>
<li>le code 138 - Router Renumbering</li>
<li>le code 139 - ICMP Node Information Query</li>
<li>le code 140 - ICMP Node Information Response</li>
<li>le code 144 - Home Agent Address Discovery Request Message</li>
<li>le code 145 - Home Agent Address Discovery Reply Message</li>
<li>le code 146 - Mobile Prefix Solicitation</li>
<li>le code 147 - Mobile Prefix Advertisement</li>
</ul>
<p><em><strong>Note</strong> : Il semble, selon le manpage <a href="http://man.openbsd.org/OpenBSD-current/man4/icmp6.4" rel="external">icmp6(4)</a>,
que les codes 144 à 147 ne soient pas gérés… par OpenBSD !</em></p>
<p>L&rsquo;IANA recommande aussi de filtrer - soit <code>drop</code>, soit <code>reject</code> - <em>à la
discrétion de l&rsquo;administrateur</em> - tous les codes suivants :</p>
<p>⇒ ICMP :</p>
<ul>
<li>code 6/0 - Alternate Host Address</li>
<li>code 15 - Information Request</li>
<li>code 16 - Information Reply</li>
<li>code 17 - Address Mask Request</li>
<li>code 18 - Address Mask Reply</li>
<li>code 30 - Traceroute</li>
<li>code 31 - Datagram Conversion Error</li>
<li>code 32 - Mobile Host Redirect</li>
<li>code 33 - IPv6 Where-Are-You</li>
<li>code 34 - IPv6 I-Am-Here</li>
<li>code 35 - Mobile Registration Request</li>
<li>code 36 - Mobile Registration Reply</li>
<li>code 37 - Domain Name Request</li>
<li>code 38 - Domain Name Reply</li>
<li>code 38 - SKIP</li>
</ul>
<p><strong>Les autres codes, icmp et icmp6, sont à &ldquo;limiter&rdquo; en entrée et/ou en sortie…</strong> <br>
<em>Pour en savoir plus, veuillez ABSOLUMENT vous informer - cf, la documentation dans la note finale !</em></p>
<p>Ce qui donne pour le propos les règles suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># macros</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blockicmp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block drop quick on egress inet proto icmp icmp-type&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blockicmplog</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block drop quick log on egress inet proto icmp icmp-type&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blockicmp6</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;block drop quick on egress inet6 proto icmp6 icmp6-type&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inpassicmplan</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass in quick on egress inet proto icmp from egress:network to egress icmp-type&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">inpassicmpwan</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass in quick on egress inet proto icmp from any to egress icmp-type&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">outpassicmplan</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass out quick on egress inet proto icmp from egress to egress:network icmp-type&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">outpassicmpwan</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;pass out quick on egress inet proto icmp from egress to any icmp-type&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_types</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{ echoreq unreach timex paramprob }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># statefull tracking options</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp_sto</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;keep state (max-src-conn-rate 3/1)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…) # autres macros</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set block-policy return</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…) # autres set</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># block icmp</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp 3 code 6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp 3 code 8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmplog 4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp 6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp 15</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp 16</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 137</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 138</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 139</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 140</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 144</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 145</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 146</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$blockicmp6 147</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…) # autres block si nécessaires</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…) </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># icmp in</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmplan 0 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmplan 3 code 0 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmplan 3 code 1 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmpwan 3 code 3 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmpwan 8 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmpwan 11 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$inpassicmplan 12 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># icmp out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmplan 0 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmplan 3 code 0 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmplan 3 code 1 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmpwan 3 code 3 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmpwan 8 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmpwan 11 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$outpassicmplan 12 $icmp_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># icmpv6 (in+out)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass quick inet6 proto icmp6 icmp6-type $icmp6_types $icmp_sto</span>
</span></span></code></pre></div><hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://www.openbsd.org/faq/pf/index.html" rel="external">https://www.openbsd.org/faq/pf/index.html</a></li>
<li><a href="https://home.nuug.no/~peter/pf/en/long-firewall.html" rel="external">https://home.nuug.no/~peter/pf/en/long-firewall.html</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Documentation sur l&#39;usage du parefeu, nommé PF, sous OpenBSD]]></summary>
        <published>2020-01-19T06:35:57+02:00</published>
        <updated>2023-04-30T17:05:08+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9b97d0f9-8b27-8720-a3b7-c4b1a661d5f6</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-terminal/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion d&#39;un terminal ou d&#39;une console sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Terminal" scheme="http://doc.huc.fr.eu.org/fr/tags/terminal/" />
        <content type="html"><![CDATA[<h2 id="comment-télécharger-en-ligne-de-commande-sous-openbsd">Comment télécharger en ligne de commande sous OpenBSD</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>Il n&rsquo;y a ni wget ni curl par défaut !</strong></div>

<p>Mais il y a la commande <code>ftp</code> qui les remplace très bien, même pour
télécharger un fichier en http :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ftp -o /chemin/vers/fichier.zip http://URL.com/fichier.zip
</span></span></code></pre></div><h2 id="gestion-des-erreurs">Gestion des erreurs</h2>
<h3 id="error-opening-terminal-unknown">Error opening terminal: unknown</h3>
<p>Vous exécutez une commande, telle que l&rsquo;ouverture d&rsquo;un éditeur texte, -
pour l&rsquo;exemple : <code>vi</code> ou <code>nano</code> - et le système vous répond par cette
erreur :</p>
<p><code>Error opening terminal: unknown</code></p>
<p>La raison ? Le système ne reconnaît pas le TERMinal !</p>
<p>Commencez par vérifier quel est ce fameux terminal non reconnu :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ tset -s
</span></span><span style="display:flex;"><span><span style="color:#ef6155">TERM</span><span style="color:#5bc4bf">=</span>vt220
</span></span></code></pre></div><p>Modifions le :</p>
<p><code>$ export TERM=vt100</code></p>
<p>Vérifier la prise en charge de ce terminal avec la commande <code>tset</code>,
ci-dessus !</p>
<p>Normalement, vous pourrez exécuter à nouveau le lancement de votre
éditeur de texte console préféré, ou la commande console qui posait
problème !</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour le terminal sous OpenBSD]]></summary>
        <published>2020-01-19T06:31:00+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0dcb2cbd-199f-e6d2-69a9-e6a2ac167476</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-session/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion de la session utilisateur / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Session" scheme="http://doc.huc.fr.eu.org/fr/tags/session/" />
        <content type="html"><![CDATA[<h2 id="fichier-profile">Fichier <code>~/.profile</code></h2>
<p>Paramétrez vos variables d&rsquo;environnements et vos
<a class="inside" href="/fr/sys/openbsd/tip-alias/" title="Lien interne vers l&#39;article : 'Les alias / OpenBSD'">alias</a>
 dans votre fichier
personnel <code>~/.profile</code>.</p>
<h2 id="environnement-ksh">Environnement ksh</h2>
<p>Sous OpenBSD, l&rsquo;environnement par défaut est le
<a class="inside" href="/fr/sys/openbsd/tip-pdksh/" title="Lien interne vers l&#39;article : 'KSH : Korn shell'">Public Domain Korn Shell</a>
.</p>
<h2 id="démarrer-la-session-graphique-automatiquement-sans-xdm">Démarrer la session graphique automatiquement sans XDM</h2>
<p>En mettant ces lignes //à la fin du// fichier <code>~/.profile</code>, votre
session graphique sera lancée dès que vous vous connecterez dans le tty1
<em>(celui par défaut)</em>.</p>
<p>Adaptez le fichier <code>~/.xinitrc</code> pour choisir votre session :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">if [ &#34;$(tty)&#34;</span> <span style="color:#5bc4bf">=</span><span style="color:#48b685">= &#34;/dev/ttyC0&#34; ]; then
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    startx</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces de gestion des sessions utilisateurs sous OpenBSD]]></summary>
        <published>2020-01-19T06:24:37+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:842b4a4d-4c7f-2ccc-75df-dc41fc208eae</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/sct/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: sct : Gestion de la température de couleur de l&#39;écran / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="sct" scheme="http://doc.huc.fr.eu.org/fr/tags/sct/" />
        <content type="html"><![CDATA[<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>sct</code></strong>.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Quelques styles de température de couleur :</p>
<p>⇒ Feu de camp : <code>:$ sct 4500</code></p>
<p>⇒ Tempête de poussière sur Mars : <code>:$ sct 2000</code></p>
<p>⇒ Café gratuit toute la nuit : <code>:$ sct 8000</code></p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/sct/#man-sct">man sct</a></li>
</ul>
<h3 id="man-sct">man sct</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>sct</strong> [temp] <br>
<strong>sct version</strong></p>
<h4 id="description">Description</h4>
<p><strong>sct</strong> est un outil léger pour paramétrer la température de l&rsquo;écran.
Si l&rsquo;argument optionnel <code>temp</code> est donné, la température de couleur est
configurée à cette valeur.</p>
<p>Les arguments sont les suivants :</p>
<ul>
<li><code>temp</code> : optionnel, spécifie la température.</li>
<li><strong>version</strong> : affiche le numéro de <strong>version</strong> et les informations de
droits d&rsquo;auteur de sct sur la sortie standard, puis termine.</li>
</ul>
<p><strong>sct</strong> attend une valeur de température entre 1000 et 10000. La valeur
de température par défaut est de 6500.</p>
<h4 id="statut-de-sortie">Statut de sortie</h4>
<p>L&rsquo;utilitaire <strong>sct</strong> sort avec un code <code>0</code> en cas de succès, et un code
supérieur à 0 si une erreur existe.</p>
<h4 id="exemples">Exemples</h4>
<p>⇒ Exécuter <strong>sct</strong> pour régler la température de l&rsquo;écran sur un style
&ldquo;feu de camp&rdquo; : <code>:$ sct 4500</code></p>
<p>⇒ Afficher les informations de version et de droits d&rsquo;auteur de sct sur
la sortie standard et sortir avec succès : <code>:$ sct version</code></p>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li><a href="http://man.openbsd.org/Xorg.1" rel="external">Xorg(1)</a>, <a href="http://man.openbsd.org/xrandr.1" rel="external">xrandr(1)</a>, <a href="http://man.openbsd.org/X.7" rel="external">X(7)</a>, <a href="http://man.openbsd.org/XStandards.7" rel="external">XStandards(7)</a></li>
</ul>
<h4 id="normes">Normes</h4>
<p>L&rsquo;utilitaire <strong>sct</strong> suit et utilise les normes XStandards(7).</p>
<h4 id="histoire">Histoire</h4>
<p>La première version de l&rsquo;utilitaire <strong>sct</strong> est apparue en Novembre 2015
dans l&rsquo;article suivant : \</p>
<ul>
<li><a href="http://www.tedunangst.com/flak/post/sct-set-color-temperature" rel="external">http://www.tedunangst.com/flak/post/sct-set-color-temperature</a></li>
</ul>
<h4 id="auteurs">Auteurs</h4>
<p>L&rsquo;utilitaire <strong>sct</strong> a été écrit par Ted Unangst [[tedu@openbsd.org]],
puis ensuite amélioré par Joerg Jung [[mail@umaxx.net]].</p>
<h4 id="bogues">Bogues</h4>
<p><strong>sct</strong> arrondit les valeurs de température par palier de 500.</p>
<h4 id="page-daccueil">Page d&rsquo;accueil</h4>
<ul>
<li><strong><a href="https://www.umaxx.net" rel="external">https://www.umaxx.net</a></strong></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer la température de couleur de l&#39;écran avec l&#39;outil &#39;sct&#39; sous OpenBSD]]></summary>
        <published>2020-01-19T05:11:23+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:66c5934f-b402-d384-59f7-70a94aa36712</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/mplayer/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MPlayer / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="MPlayer" scheme="http://doc.huc.fr.eu.org/fr/tags/mplayer/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>MPlayer</strong> est un lecteur multimédias.</p>
<p>Il peut vous faire écouter des fichiers au format MPEG/VOB, AVI,
ASF/WMA/WMV, FLV, RM, QT/MOV/MP4, Ogg/OGM, MKV, VIVO, FLI, NuppelVideo,
yuv4mpeg, FILM et RoQ. Mais vous pouvez aussi regarder des films au
format VCD, SVCD, DVD, 3ivx, DivX 3/4/5, WMV, et même H.264.</p>
<p>MPlayer prend en charge un grand nombre de sortie vidéos. Il fonctionne
avec X11, Xv, OpenGL et en options AAlib ou SDL.</p>
<h3 id="saveurs">Saveurs</h3>
<p>Voici les différentes saveurs de paquets MPlayer :</p>
<ul>
<li><code>aa</code> : active l&rsquo;ASCII Art, et requiert la bibliothèque graphique <strong>aalib</strong></li>
<li><code>jack</code> : active l&rsquo;utilisation de jack, et requiert le paquet audio <strong>jack</strong></li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>mplayer</code></strong>.</p>
<h2 id="utilisation">Utilisation</h2>
<p>L&rsquo;utilisation de <strong>l&rsquo;interface graphique de MPlayer est dépréciée</strong>
et n&rsquo;est pas recommandée sur aucune des architectures supportées par
OpenBSD. Elle n&rsquo;est donc <strong>pas intégrée dans le paquet de MPlayer</strong>.</p>
<p>Utilisez gnome-player ou smplayer à la place.</p>
<p>Mencoder n&rsquo;est pas censé faire un bon travail de multiplexage avec des
formats de conteneurs autres qu&rsquo;AVI ou MPEG.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="arm">arm</h3>
<p>Il est possible de rencontrer des problèmes de lenteurs vidéo. Dans ce
cas, vous pouvez désactiver la rotation de l&rsquo;écran de X.org dans le
fichier <code>/etc/X11/xorg.conf</code>.</p>
<p>Selon votre configuration, vous pouvez passer les options <code>-framedrop</code>
ou <code>-hardframedrop</code> à l&rsquo;usage de mplayer.</p>
<h3 id="i386">i386</h3>
<p>Puisque les codecs open source sont de bonne qualité, à l&rsquo;heure actuelle,
les codecs Win32 sont maintenant désactivés.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le lecteur multimédia MPlayer sous OpenBSD]]></summary>
        <published>2020-01-19T05:05:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c04a8523-2865-0fa1-3ee1-d2a59fe0494b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/lumina/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Lumina (environnement de bureau graphique) / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Lumina" scheme="http://doc.huc.fr.eu.org/fr/tags/lumina/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le bureau <strong>Lumina</strong> !</p>
<p>Page du projet : <a href="https://lumina-desktop.org" rel="external">https://lumina-desktop.org</a></p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>lumina</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="gestionnaire-de-connexion">Gestionnaire de connexion</h3>
<h4 id="fichier-xsession">Fichier <code>~/.xsession</code></h4>
<p>Disponible à partir d&rsquo;OpenBSD 6.1 !</p>
<p>Créer/modifier le fichier de session <code>~/.xsession</code>, et y ajouter à minima :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PATH</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$PATH:/usr/local/bin start-lumina-desktop</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il semble que l&rsquo;ajout du PATH soit nécessaire pour le démarrage par le
biais de xenodm !</div>

<p><strong>Pensez à <a class="inside" href="/fr/sys/openbsd/rcctl/#red%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">redémarrer le service</a>

<code><a class="inside" href="/fr/sys/openbsd/xenodm/" title="Lien interne vers l&#39;article : 'xenodm : Gestionnaire de sessions X pour OpenBSD'">xenodm</a>
</code> !</strong></p>
<h3 id="impression">Impression</h3>
<p>Merci de lire notre page du service <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">cups</a>
,
pour configurer correctement la gestion de l&rsquo;impression ;)</p>
<h3 id="réseau">Réseau</h3>
<h4 id="samba">Samba</h4>
<p>Pour l&rsquo;instant, cela ne semble pas possible !</p>
<h3 id="usb">USB</h3>
<p>Il faut plutôt s&rsquo;inspirer d&rsquo;une des méthodes fournies dans notre page
&ldquo;<strong>[[tutoriel:openbsd-mount-usb|Monter un disque / une clé USB en tant qu’utilisateur]]</strong>&rdquo; ;-)</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le bureau graphique nommé &#39;Lumina&#39; sous OpenBSD]]></summary>
        <published>2020-01-19T04:52:52+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a2d825bf-7b9e-65df-7707-08187fe6a648</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/intel/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion intel (pilote graphique)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="intel" scheme="http://doc.huc.fr.eu.org/fr/tags/intel/" />
        <content type="html"><![CDATA[<h2 id="configuration">Configuration</h2>
<p><strong>Le fichier de config <code>/etc/X11/xorg.conf</code> n&rsquo;existe pas, par défaut ! <br>
Il faut le créer !!!</strong></p>
<h3 id="machdepallowaperture">machdep.allowaperture</h3>
<p>Quand ajouter l&rsquo;option <code>machdep.allowaperture</code> ?</p>
<p>Si le log du serveur X vous informe du message suivant :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">$ head /var/log/Xorg.0.log
[    33.839] (WW) checkDevMem: failed to open /dev/xf86 and /dev/mem
        (Operation not permitted)
        Check that you have set &#39;machdep.allowaperture=1&#39;
        in /etc/sysctl.conf and reboot your machine
        refer to xf86(4) for details
[    33.839]    linear framebuffer access unavailable
[    33.888] (--) Using wscons driver on /dev/ttyC4
[    33.997] 
X.Org X Server 1.19.6
Release Date: 2017-12-20
</code></pre><p>Donc, comme le dit le message d&rsquo;avertissement, il est nécessaire
d&rsquo;éditer le fichier <code>/etc/sysctl.conf</code> et d&rsquo;y ajouter la variable
suivante : <code>machdep.allowaperture=1</code>, puis il faut redémarrer la machine
- non, apparemment, redémarrer le serveur X ne suffit pas !</p>
<h3 id="amélioration-du-tearing">Amélioration du tearing</h3>
<p>Si votre affichage vidéo saccade, vous souffrez de <code>tearing</code>.</p>
<p>Une manière de le régler est d&rsquo;ajouter à votre fichier <code>/etc/X11/xorg.conf</code>,
les options suivantes, dans la <code>Section &quot;Device&quot;</code> :</p>
<ul>
<li><code>Option  &quot;TearFree&quot;		&quot;true&quot;</code> - cette <strong>option principale</strong> est
par défaut désactivée ; donc, <strong>il faut l&rsquo;activer</strong> !</li>
<li><code>Option	&quot;SwapbuffersWait&quot;	&quot;true&quot;</code> - normalement cette option est
activée par défaut</li>
<li><code>Option	&quot;VSync&quot;			&quot;true&quot;</code> - normalement cette option est
activée par défaut - elle gère, entres autres, le <code>tearing vertical</code>.</li>
</ul>
<h3 id="désactiver-le-compositeur">Désactiver le compositeur</h3>
<p>Il peut être intéressant de désactiver l&rsquo;extension du compositeur ; il
faut donc rajouter la gestion de l&rsquo;option <code>Composite</code> dans la
<code>Section &quot;Extensions&quot;</code>
- bien-sûr, si cette dernière n&rsquo;existe pas dans votre fichier de config,
créez-la, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Extensions&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#776e71"># fixes tearing with vdpau/vsync</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;Composite&#34;		&#34;Disable&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span></code></pre></div><div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Si l&rsquo;ensemble peut paraître plus fluide, il faut bien
comprendre que cela désactive la gestion des ombrages de fenêtres,
entres autres…</p>
<p>De même, il est possible que votre interface graphique vous semble moins
&ldquo;léché&rdquo;.</p>
</div>
<h3 id="exemples-de-configuration">Exemples de configuration</h3>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Du fait, de l&rsquo;activation de l&rsquo;option &ldquo;HotPlug&rdquo;, dans la
section &ldquo;Device&rdquo;, il n&rsquo;est pas nécessaire de configurer certaines entrées,
telles que celles pour le clavier, la souris, le touchpad, etc…</p>
<p>ces entrées seront détectées et configurées automatiquement !</p>
</div>
<h4 id="minimum-pour-le-tearfree">minimum pour le tearfree</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Device&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Identifier	&#34;intel&#34;	</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Driver	&#34;intel&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;HotPlug&#34;		&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option  &#34;TearFree&#34;		&#34;true&#34;	#false by default	(avoid tearing)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span></code></pre></div><h4 id="fichier-de-config-fonctionnel">fichier de config fonctionnel</h4>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>L&rsquo;exemple de fichier ci-dessous est configuré pour une haute résolution
&ldquo;1920x1080&rdquo;</p>
<ul>
<li>ASSUREZ-vous que votre écran et votre GPU soit capable de gérer
celle-ci ; sinon, modifiez-le en conséquence !!!</li>
</ul>
<p><strong>Si votre écran ou votre GPU n&rsquo;est pas capable de gérer cette résolution,
à minima le serveur X ne démarrera pas ; au pire, une mauvaise
configuration peut endommager irrémédiablement votre matériel !</strong></p>
<p>Préférez commencer avec l&rsquo;exemple de base ci-dessus !</p>
</div>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Device&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Identifier	&#34;intel&#34;	#modesetting, or Intel Graphics</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Driver	&#34;intel&#34; #modesetting</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option  &#34;AccelMethod&#34;	&#34;sna&#34;	#sna by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;DDC&#34;			&#34;true&#34;	#true by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;DRI&#34;			&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;HotPlug&#34;		&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;NoAccel&#34;		&#34;false&#34;	#false by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;RelaxedFencing&#34;	&#34;true&#34;	#true if G33 Model &amp; &gt;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;SwapbuffersWait&#34;	&#34;true&#34;	#true by default (avoid tearing)</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option  &#34;TearFree&#34;		&#34;true&#34;	#false by default	(avoid tearing)</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;Throttle&#34;		&#34;true&#34;	#true by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;Tiling&#34;		&#34;true&#34;	#true by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;TripleBuffer&#34;	&#34;true&#34;	#true by default</span>
</span></span><span style="display:flex;"><span>	<span style="color:#776e71">#Option	&#34;VideoRAM&#34;		???</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">Option	&#34;VSync&#34;			&#34;true&#34;	#true by default	(avoid tearing)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Monitor&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Identifier             &#34;Monitor0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Screen&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Identifier             &#34;Screen0&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Device                 &#34;intel&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Monitor                &#34;Monitor0&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">DefaultDepth           24 #Choose the depth (16|24)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">SubSection             &#34;Display&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">Depth              16</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">Modes              &#34;1920x1080&#34; &#34;1400x1050&#34; &#34;1290X1024&#34; &#34;1280X960&#34; &#34;1024x768&#34; &#34;800x600&#34; </span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">EndSubSection</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">SubSection &#34;Display&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">Depth        		24</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">Modes				&#34;1920x1080&#34; &#34;1400x1050&#34; &#34;1290X1024&#34; &#34;1280X960&#34; &#34;1024x768&#34; &#34;800x600&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">EndSubSection</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;ServerLayout&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Identifier    &#34;Default Layout&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Screen        &#34;Screen0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<ul>
<li>le [[http://man.openbsd.org/intel.4|manpage intel(4)]]…</li>
<li>le [[http://man.openbsd.org/inteldrm.4|manpage inteldrm(4)]]</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gestion du pilote logiciel Intel sous OpenBSD]]></summary>
        <published>2020-01-19T04:43:09+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2294a0a3-b7be-7037-73c4-ebd1ee1baf98</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/gigolo/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gigolo / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Gigolo" scheme="http://doc.huc.fr.eu.org/fr/tags/gigolo/" />
        <category term="GVfs" scheme="http://doc.huc.fr.eu.org/fr/tags/gvfs/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.uvena.de/gigolo/" rel="external">Gigolo</a></strong> est une interface graphique
pour se connecter facilement à des systèmes de fichiers distants utilisant
GIO/GVfs. Il permet de rapidement connecter/monter un système de fichiers
distant et de gérer des signets à ce propos.</p>
<p>GVfs est un système de fichiers virtuel dans l&rsquo;espace utilisateur,
succédant à GnomeVfs mais ne dépendant pas de Gnome lui-même. Il requiert
seulement une version récente de GLib et un système <a class="inside" href="/fr/sys/openbsd/dbus/" title="Lien interne vers l&#39;article : 'D-Bus [système de bus de messages] / OpenBSD'">DBus</a>

proprement paramétré. Il fournit alors les accès transparent à des
ressources distantes, telles que des connexions FTP ou SFTP <em>(SSH)</em>,
<a class="inside" href="/fr/sys/openbsd/samba/" title="Lien interne vers l&#39;article : 'OpenBSD : Introduction à Samba'">SMB</a>
 <em>(partages Windows)</em>, ou
des ressources spéciales telles que la Corbeille <em>(trash://)</em>, la Gravure
<em>(burn://)</em> ou même les accès à votre caméra/appareil photo digital
<em>(gphoto2://)</em>.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>gigolo</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<p>Dans un premier temps, le plus simple est de créer un ou plusieurs signets :</p>
<ul>
<li>Cliquez sur le menu <strong><u>É</u>diter &gt; <u>M</u>odifier les signets Ctrl+B</strong>…</li>
<li>Cliquez sur le bouton [A<u>j</u>outer] ; vous obtiendrez la fenêtre
&lsquo;Créer un signet&rsquo;.</li>
</ul>
<p>Cela vous permettra de créer des signets pour un des services suivants :</p>
<ul>
<li>FTP</li>
<li>Partage Windows (Samba)</li>
<li>SSH</li>
<li>Webdav</li>
<li>Webdav (sécurisé)</li>
</ul>
<hr>
<ul>
<li>Donnez un nom à ce nouveau signet</li>
<li>Choisissez le type de service</li>
<li>Indiquez le serveur à contacter</li>
<li>Indiquez le port du serveur à contacter</li>
<li>Indiquez le dossier distant (optionnel)</li>
<li>Indiquez votre nom d&rsquo;utilisateur : c&rsquo;est votre identifiant nécessaire
vers le service, si besoin.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>Retrouvez de la documentation dans <code>/usr/local/share/doc/gigolo/</code>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le logiciel nommé &#39;Gigolo&#39; pour vous connecter à des systèmes de fichiers distants, sous OpenBSD]]></summary>
        <published>2020-01-19T04:33:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ee89ddd0-4af6-617a-6ace-219f6c7224e2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/dbus/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: D-Bus [système de bus de messages] / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="dbus" scheme="http://doc.huc.fr.eu.org/fr/tags/dbus/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://dbus.freedesktop.org/" rel="external">D-Bus</a></strong> est un système de bus de messages.
C&rsquo;est un moyen simple pour permettre aux applications de discuter entre elles.</p>
<p>En plus de la communication inter-processus (IPC), D-Bus aide à coordonner
le cycle de vie des processus ; il est ainsi plus simple et fiable de
coder une &ldquo;instance unique&rdquo; d&rsquo;une application ou d&rsquo;un service (daemon)
et à exécuter les applications et services à la demande, lorsque leurs
services sont requis.</p>
<h2 id="installation">Installation</h2>
<ul>
<li><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>

le paquet <code>dbus</code></strong> et ensuite,</li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">activez les services</a>

<code><a class="inside" href="/fr/sys/openbsd/apm/" title="Lien interne vers l&#39;article : 'Apm : Programme de contrôle de la gestion de l&#39;énergie et de l&#39;hibernation'">apmd</a>
</code> et
<code><a class="inside" href="/fr/sys/openbsd/consolekit/" title="Lien interne vers l&#39;article : 'Consolekit2 (bus de messages) / OpenBSD'">messagebus</a>
</code></li>
<li>et <a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">démarrez</a>
-les.</li>
</ul>
<h2 id="configuration">Configuration</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Certains gestionnaires de sessions, tel que <a class="inside" href="/fr/sys/openbsd/gnome/" title="Lien interne vers l&#39;article : 'OpenBSD : Utiliser Gnome'">Gnome</a>
,
gèrent D-Bus toujours de manière pratique automatiquement !</p>
<p><strong>Les modifications suivantes ne seront donc pas prises en compte !!!</strong></p>
</div>

<p>Pour démarrer une instance du service de D-Bus, il faut ajouter le code
suivant à votre script gérant votre session X, avant le démarrage de
gestionnaire de fenêtre :</p>
<h3 id="fichier-xinitrc">Fichier <code>~/.xinitrc</code></h3>
<p>Pour rappel, ce fichier sert à démarrer un environnement de bureau
depuis votre session locale, sans exécution d&rsquo;un gestionnaire d&rsquo;affichage :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -x /usr/local/bin/dbus-launch -a -z <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">DBUS_SESSION_BUS_ADDRESS</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>	eval <span style="color:#48b685">`</span>dbus-launch --sh-syntax --exit-with-session<span style="color:#48b685">`</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><h3 id="fichier-xsession">Fichier <code>~/.xsession</code></h3>
<p>Pour rappel, ce fichier est à utiliser en relation avec un gestionnaire
d&rsquo;affichage, tel <a class="inside" href="/fr/sys/openbsd/xenodm/" title="Lien interne vers l&#39;article : 'xenodm : Gestionnaire de sessions X pour OpenBSD'">xenodm</a>
 :</p>
<pre tabindex="0"><code>if [ -x /usr/local/bin/dbus-launch -a -z &#34;${DBUS_SESSION_BUS_ADDRESS}&#34; ]; then
	eval `dbus-launch --sh-syntax --exit-with-x11`
fi
</code></pre><h2 id="documentation">Documentation</h2>
<p>N&rsquo;oubliez pas de lire le fichier <code>/usr/local/share/doc/pkg-readmes/dbus</code></p>
<p>Vous pouvez aussi lire :</p>
<ul>
<li>la documentation à-propos : <code>/usr/local/share/doc/dbus/</code></li>
<li>et des exemples depuis <code>/usr/local/share/examples/dbus/</code>,
voire <code>/usr/local/share/examples/dbus-glib/</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le système de bus de messages sous OpenBSD, nommé &#39;dbus&#39;.]]></summary>
        <published>2020-01-19T04:23:24+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:43234f45-3924-1f5b-d76d-ffc96d3ef8b8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/cwm/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: cwm (gestionnaire de fenêtres) / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="cwm" scheme="http://doc.huc.fr.eu.org/fr/tags/cwm/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>cwm</strong> est un gestionnaire de fenêtres, léger et efficace, présent par
défaut dans OpenBSD.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Si vous utilisez le gestionnaire de connexion <a class="inside" href="/fr/sys/openbsd/xenodm/" title="Lien interne vers l&#39;article : 'xenodm : Gestionnaire de sessions X pour OpenBSD'">xenodm</a>
,
présent par défaut lui-aussi, vous pouvez démarrer <code>cwm</code> en l&rsquo;appelant
dans le fichier <code>~/.xsession</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">xsetroot -solid steelblue &amp;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># feh --bg-scale /Images/background.jpg</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">cwm</span>
</span></span></code></pre></div><p>La première ligne permet de définir une couleur de fond. Vous pouvez la
remplacer par la seconde actuellement commentée afin de définir un fond
d&rsquo;écran à partir d&rsquo;une image.</p>
<h3 id="prise-en-main">Prise en main</h3>
<p><code>cwm</code> peut se contrôler aussi bien avec le clavier que la souris.</p>
<ul>
<li>
<p>Par la suite, nous utiliserons les mêmes abréviations que dans le fichier
de configuration, à savoir :</p>
<ul>
<li><code>C</code> : Ctrl</li>
<li><code>M</code> : Alt</li>
<li><code>S</code> : Shift</li>
<li><code>4</code> : Touche &ldquo;windows&rdquo;</li>
</ul>
</li>
<li>
<p>Pour déplacer une fenêtre, il faut maintenir M appuyé puis glisser-déposer
avec la souris.</p>
</li>
<li>
<p>Pour la redimensionner, c&rsquo;est avec un clic-milieu.</p>
</li>
<li>
<p>Un clic-gauche sur le bureau vous affiche la liste des fenêtres ouverts.</p>
</li>
<li>
<p>Un clic-milieu affiche la liste des groupes de fenêtres (sortes d&rsquo;espace
de travail).</p>
</li>
<li>
<p>Un clic-droit affiche le menu des applications que vous aurez configuré
dans le fichier de configuration.</p>
</li>
</ul>
<p>Les raccourcis claviers par défaut sont (non-exhaustif) :</p>
<ul>
<li><code>M-?</code> : invite de commande pour lancer un programme.</li>
<li><code>CM-Entrée</code> : ouvre un terminal.</li>
<li><code>CM-Suppr</code> : verrouille la session.</li>
<li><code>M-Tab</code> : circule entre les fenêtres.</li>
<li><code>M-/</code> : recherche une fenêtre. Appuyez ensuite sur C-a pour les lister
toutes.</li>
<li><code>CM-x</code> : ferme la fenêtre.</li>
<li><code>CM-f</code> : met la fenêtre en plein écran.</li>
<li><code>CM-=</code>, <code>CMS-=</code>, <code>CM-m</code> : respectivement, maximise la fenêtre
verticalement, horizontalement et totalement.</li>
<li><code>CMS-r</code> : relance cwm</li>
<li><code>CMS-q</code> : quitte cwm</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="fichier-cwmrc">Fichier <code>~/.cwmrc</code></h3>
<p>La configuration de cwm se déroule en éditant un fichier <code>.cwmrc</code> dans
votre dossier personnel : <code>~/.cwmrc</code></p>
<p>Vous pouvez y définir notamment :</p>
<h4 id="apparence">Apparence</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">borderwidth 2                  # Épaisseur des bordures</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color activeborder &#34;#2aa198&#34;   # Couleur des bordures des fenêtres sélectionnées</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color inactiveborder &#34;002B36&#34;  # Couleur des bordures si la fenêtre est inactive</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">gap 20 0 0 0                   # je souhaite avoir une marge en haut de l&#39;écran</span>
</span></span><span style="display:flex;"><span>                               <span style="color:#776e71"># de 20 pixels</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Configuration de l&#39;apparence des menus</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color font           &#34;#839496&#34; # Couleur du texte</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color selfont        &#34;#eee&#34;    # Couleur du texte sélectionnée</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color menubg         &#34;#002b36&#34; # Couleur d&#39;arrière plan</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">color menufg         &#34;#2aa198&#34; # Couleur de bordure des éléments sélectionnées</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fontname &#34;Hack:pixelsize</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">14&#34;   # La police des menus</span>
</span></span></code></pre></div><h4 id="commandes-personnalisées">Commandes personnalisées</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Les commandes terminal et de verouillage.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Autant utiliser les défauts d&#39;OpenBSD</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command term st</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command lock &#34;slock&#34; # activer avec C-M-Suppr</span>
</span></span></code></pre></div><h4 id="menu-par-clic-droit">Menu par clic-droit</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;   Web   &#34; firefox</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;   Mail  &#34; thunderbird</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;  Files  &#34; pcmanfm</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;&gt;&gt; next  &#34; &#34;mpc next&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;&lt;&lt; prev  &#34; &#34;mpc prev&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;|&gt; toggle&#34; &#34;mpc toggle&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">command &#34;   top   &#34; &#34;xterm -e top&#34;</span>
</span></span></code></pre></div><h4 id="groupes-automatiques">Groupes automatiques</h4>
<p>Vous pouvez mettre des fenêtres directement dans certains groupes pour
facilement vous y retrouver :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Groupes, à retrouver avec xprop</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># autogroup n &#34;name,class&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">autogroup 2 &#34;Navigator,Firefox&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">autogroup 3 &#34;mutt,mutt&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">autogroup 3 &#34;mutt,st-256color&#34;</span>
</span></span></code></pre></div><h4 id="raccourcis-clavier">Raccourcis clavier</h4>
<h5 id="les-groupes-facilement-accessibles-pour-un-clavier-azerty">Les groupes facilement accessibles pour un clavier azerty</h5>
<p>Pour voir un groupe : <code>M-n</code> où <code>n</code> est le chiffre correspondant au groupe.</p>
<p>Sur un clavier azerty, c&rsquo;est <kbd>&amp;é&quot;&rsquo;(</kbd>…</p>
<p>Pour envoyer une fenêtre dans un groupe, c&rsquo;est <code>MS-n</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-ampersand        group-only-1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-eacute           group-only-2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-quotedbl         group-only-3</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-apostrophe       group-only-4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-parenleft        group-only-5</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-minus            group-only-6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-egrave           group-only-7</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-underscore       group-only-8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-ccedilla         group-only-9</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-agrave           group-toggle-all</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Déplacer les fenêtres dans un groupe</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-ampersand        window-movetogroup-1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-eacute           window-movetogroup-2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-quotedbl         window-movetogroup-3</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-apostrophe       window-movetogroup-4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-parenleft        window-movetogroup-5</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-minus            window-movetogroup-6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-egrave           window-movetogroup-7</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-underscore       window-movetogroup-8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-ccedilla         window-movetogroup-9</span>
</span></span></code></pre></div><h5 id="agencement-en-tuile">Agencement en tuile</h5>
<p>Ces raccourcis permettent d&rsquo;agencer très rapidement les fenêtres en
tuile pour occuper tout l&rsquo;espace disponible (comme dwm)</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Du tiling !!!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-t window-vtile</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-Return window-vtile</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">bind-key MS-t window-htile</span>
</span></span></code></pre></div><h5 id="raccourcis-clavier-personnels">Raccourcis clavier personnels</h5>
<p>Vous pouvez lancer des commandes avec un raccourci clavier. Par exemple
ceci ouvre firefox :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">bind-key M-w firefox</span>
</span></span></code></pre></div><h4 id="redimensionnement-avec-clic-droit">Redimensionnement avec clic-droit</h4>
<p>Pour redimensionner avec le bouton droit de la souris, on peut désactiver
le raccourci précédent :</p>
<pre tabindex="0"><code># Souris
# Désactive le redimensionnement avec le clic milieu
unbind-mouse M-2
# Alt+ clic droit redimensionne
bind-mouse M-3 window-resize
</code></pre><h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li><a href="http://man.openbsd.org/cwm" rel="external">man cwm</a></li>
<li><a href="http://man.openbsd.org/cwmrc" rel="external">man cwmrc</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>Cette documentation a été écrite de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le gestionnaire de fenêtres nommé &#39;cwn&#39; sous OpenBSD]]></summary>
        <published>2020-01-19T04:11:24+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:04f29b23-ab9d-c3ff-a74d-2ccbd1ed6869</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/iridium/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Iridium / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="iridium" scheme="http://doc.huc.fr.eu.org/fr/tags/iridium/" />
        <category term="Chromium" scheme="http://doc.huc.fr.eu.org/fr/tags/chromium/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Iridium est une libre, ouverte, et gratuite modification du code de la
base du navigateur <a class="inside" href="/fr/sys/openbsd/chromium/" title="Lien interne vers l&#39;article : 'Chromium / OpenBSD'">Chromium</a>
,
avec de la confidentialité activée sur beaucoup de clés : la transmission
automatique de requêtes partielles, les mots clés, la télémétrie aux
services centralisant sont inhibés et exécutés que seulement avec le
consentement.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>iridium</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="extensions">Extensions</h3>
<h4 id="keepassxc-browser">KeePassXC-Browser</h4>
<p>Depuis OpenBSD 6.6, le logiciel de confidentialité
<strong><a class="inside" href="/fr/sys/openbsd/keepassxc/" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC</a>
</strong> est installable.</p>
<p>Pour fonctionner correctement avec iridium, il est nécessaire
d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 le
module <strong>KeePassXC-Browser</strong>.</p>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk" rel="external">https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk</a></li>
</ul>
<p>Lire la page <strong>KeePassXC</strong> pour avoir plus d&rsquo;informations concernant le
module <a class="inside" href="/fr/sys/openbsd/keepassxc/#keepassxc-browser" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC-Browser</a>
</p>
<h5 id="unveil-et-keepassxc-proxy">Unveil et KeepassXC Proxy</h5>
<p>Ajouter au <a href="/fr/sys/openbsd/iridium/#unveil">fichier de configuration unveil</a> de iridium <code>unveil.main</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin r</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin/keepassxc-proxy rx</span>
</span></span></code></pre></div><p>Ainsi le proxy de KeePassXC pourra communiquer avec le module
KeePassXC-Browser.</p>
<h3 id="support-pledge-et-unveil">Support Pledge et Unveil</h3>
<p>iridium sur OpenBSD est sécurisé par pledge(2) et unveil(2) - afin de
limiter les appels systèmes et les accès au système de fichier.</p>
<p>Retrouvez ces fichiers dans le répertoire <code>/etc/chromium</code> et tout particulièrement :</p>
<ul>
<li><code>/etc/iridium/pledge.main</code></li>
<li><code>/etc/iridium/unveil.main</code></li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="protonmail">Protonmail</h3>
<p>Si votre navigateur plante lorsque vous utilisez protonmail ou une autre
bibliothèque de chiffrement javascript, dirigez-vous dans <code>chrome://flags</code>
puis indiquez :</p>
<ul>
<li><code>Experimental Validate Asm.js and convert to WebAssembly when valid</code> à <code>false</code>.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Pas de fichier pkg_readme ! ;)</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Iridium : navigateur web open source, basé sur Chromium, sous OpenBSD]]></summary>
        <published>2020-01-19T03:53:48+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0c4f25a4-7d0f-b82b-d74b-5c57d06d0df2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/firefox-esr/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Firefox ESR / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Firefox" scheme="http://doc.huc.fr.eu.org/fr/tags/firefox/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://www.mozilla.org/firefox/" rel="external">Firefox-esr</a></strong> est un navigateur web
conforme aux normes, pleinement équipés, construit sur la base du code
de Mozilla par des centaines de contributeurs dans le monde. Il est
extensible à-travers des centaines d&rsquo;extensions, contributions
d&rsquo;utilisateurs, et de fonctionnalités :</p>
<ul>
<li>Navigation par onglets améliorée, avec regroupement des onglets</li>
<li>Navigation privée</li>
<li>Vérification orthographique</li>
<li>Suggestions de recherche</li>
<li>Restauration de session</li>
<li>Lecteurs Web (RSS)</li>
<li>Titres en direct</li>
<li>Recherche intégrée</li>
<li>Signets en direct</li>
<li>Bloqueur de Pop-up</li>
<li>Protection contre le phishing</li>
<li>Gestionnaire de Moteur de Recherche</li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>firefox-esr</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="accélération-graphique">Accélération Graphique</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>Ces fonctionnalités ne sont utilisables qu&rsquo;avec Firefox Quantum, et
tout particulièrement à partir de la version 59.x !</strong></p>
<p><strong>Il est important que votre architecture matérielle gère
OpenGL 4, et WebGL 2 ; autrement, OUBLIEZ !</strong></p>
</div>

<p>⇒ Par défaut, l&rsquo;accélération graphique OpenGL est désactivée. Il est
possible de l&rsquo;activer de deux manières :</p>
<ul>
<li>Ajoutez à votre environnement la variable suivante : <code>MOZ_ACCELERATED=1</code></li>
<li>L&rsquo;autre moyen étant d&rsquo;utiliser l&rsquo;<a href="/fr/sys/openbsd/firefox-esr/#aboutconfig">éditeur de configuration</a>
et de modifier la valeur binaire <code>layers.acceleration.force-enable</code>
pour la positionner sur <code>true</code>.</li>
<li>Pour vérifier le <a href="/fr/sys/openbsd/firefox-esr/#aboutsupport">support</a>, cherchez les
champs <code>HW_COMPOSITING</code> et <code>OPENGL_COMPOSITING</code> dans la section
<strong>Accélération graphique</strong>.</li>
</ul>
<p>⇒ Pour activer le compositeur basé sur Rust, deux manières possibles :</p>
<ul>
<li>Ajoutez à votre environnement la variable suivante : <code>MOZ_WEBRENDER=1</code></li>
<li>L&rsquo;autre moyen étant d&rsquo;utiliser l&rsquo;<a href="/fr/sys/openbsd/firefox-esr/#aboutconfig">éditeur de configuration</a>
et de modifier la valeur binaire <code>gfx.webrender.enabled</code> pour la
positionner sur <code>true</code>.</li>
<li>Pour vérifier le <a href="/fr/sys/openbsd/firefox-esr/#aboutsupport">support</a>, cherchez le
champ <code>WEBRENDER</code> dans la section <strong>Accélération graphique</strong>.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si vous voulez avoir plus de détails, lisez : <br>
<a href="https://wiki.mozilla.org/Platform/GFX/Quantum_Render" rel="external">https://wiki.mozilla.org/Platform/GFX/Quantum_Render</a>  !</div>

<h3 id="anti-aliasing">Anti-aliasing</h3>
<p>Pour désactiver l&rsquo;anti-aliasing, il est nécessaire de créer la variable
d&rsquo;environnement suivante <code>GDK_USE_XFT=0</code>.</p>
<h3 id="d-bus">D-Bus</h3>
<p>Pour une intégration propre avec les composants des environnements de
bureau, Firefox-ESR a besoin d&rsquo;une instance de D-Bus fonctionnelle.</p>
<p>Veuillez lire <a class="inside" href="/fr/sys/openbsd/dbus/" title="Lien interne vers l&#39;article : 'D-Bus [système de bus de messages] / OpenBSD'">D-Bus [système de bus de messages] / OpenBSD</a></p>
<h3 id="audio-vidéo-html5">Audio, Vidéo HTML5</h3>
<p>Pour <strong>ajouter le support audio et vidéo HTML5</strong>,
<strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code><a class="inside" href="/fr/sys/openbsd/ffmpeg/" title="Lien interne vers l&#39;article : 'FFmpeg / OpenBSD'">ffmpeg</a>
</code></strong>.</p>
<h3 id="kerberosv">KerberosV</h3>
<p>Pour utiliser Firefox en mode KerberosV :</p>
<ul>
<li>il faut *<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

le paquet &ldquo;heimdal&rdquo;**.</li>
<li>puis configurer votre client Kerberos.</li>
<li>ajouter à votre environnement la variable
<code>LD_LIBRARY_PATH=/usr/local/heimdal/lib</code>
<ul>
<li><em>ceci peut être fait de multiple façons, via le shell, via un script.</em>,</li>
<li>ou modifier <code>shlib_dirs</code> dans le fichier <code>/etc/rc.conf.local</code></li>
</ul>
</li>
</ul>
<p>Si vous désirez spécifier l&rsquo;usage de Kerberos en ciblant certains domaines,
écrivez &ldquo;about:config&rdquo; dans la barre d&rsquo;URL, puis modifiez la clé
<code>network.negotiate-auth.trusted-uris</code> en ajoutant votre domaine, tel que : <br>
<code>.example.com</code>.</p>
<h3 id="liens-mailto">Liens mailto</h3>
<p>À-propos de la <strong>gestion des liens mailto</strong> :</p>
<ul>
<li>Écrivez &ldquo;about:config&rdquo; dans la barre d&rsquo;URL, cherchez l&rsquo;option
<code>network.protocol-handler.app.mailto</code>.
<ul>
<li>si elle existe, vérifiez le chemin absolu de votre client mail,
tel que : <code>/usr/local/bin/thunderbird</code></li>
<li>sinon créez-la en ajoutant une &ldquo;nouvelle chaîne&rdquo; (<code>new string</code>)</li>
</ul>
</li>
</ul>
<h3 id="support-pledge-et-unveil">Support Pledge et Unveil</h3>
<p>Firefox sur OpenBSD est sécurisé par pledge(2) et unveil(2) - afin de
limiter les appels systèmes et les accès au système de fichier.</p>
<p>Par défaut, seuls les répertoires <code>/tmp</code> et <code>~/Downloads</code> sont autorisés
en écriture. De même, la lecture des fichiers locaux est autorisé en
préfixant le chemin vers le fichier par <code>file://</code>.</p>
<p>Si votre répertoire personnel <code>~/Downloads</code> n&rsquo;existe pas, créez-le puis
relancez Firefox.</p>
<ul>
<li>Depuis OpenBSD 6.7 : unveil est activé par défaut
<ul>
<li><em>présent depuis la version -current la précédant</em>.</li>
</ul>
</li>
<li>Avant OpenBSD 6.7 : Par défaut, unveil est désactivé !</li>
</ul>
<p>Les permissions pour chaque type de processus sont localisées par défaut
dans des fichiers contenus dans <code>etc/firefox</code> qui est une copie de
<code>/usr/local/lib/firefox-esr/browser/defaults/preferences/</code> lors de
l&rsquo;installation.</p>
<h4 id="gestion-mime-paquets-tiers">Gestion MIME paquets tiers</h4>
<p>Du fait d&rsquo;unveil(2), il est nécessaire de gérer finement les gestionnaires
MIME.</p>
<p>Par exemple pour permettre l&rsquo;utilisation d&rsquo;un lecteur PDF avec Firefox,
il faut :</p>
<ol>
<li>
<p>déclarer par défaut le lecteur PDF en tant gestionnaire MIME, tel que</p>
<ul>
<li>pour xpdf : <code>$ xdg-mime default xpdf.desktop application/pdf</code></li>
<li>pour mupdf : <code>$ xdg-mime default mupdf.desktop application/pdf</code></li>
</ul>
</li>
<li>
<p>modifier le fichier <code>/etc/firefox-esr/unveil.main</code> pour gérer les droits
sur le binaire correspondant, tel que :</p>
<ul>
<li>pour xpdf : <code>/usr/local/bin/xpdf rx</code></li>
<li>pour mupdf : <code>/usr/local/bin/mupdf rx</code></li>
</ul>
</li>
</ol>
<p>Ainsi vous pourrez lire le fichier PDF avec l&rsquo;option &ldquo;Ouvrir avec…&rdquo;.</p>
<hr>
<p><code>$ xdg-mime query default application/pdf</code> permet de connaître le lecteur
PDF par défaut.</p>
<h3 id="webrtc">WebRTC</h3>
<p>Le support des webcams est normalement géré par Firefox, qui par défaut
a accès aux périphériques vidéo  <code>/dev/video</code> et <code>/dev/video0</code>.</p>
<p>⇒ <strong>OpenBSD ≥ 6.9</strong> : Il faut aussi :
- activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-video/#enregistrement-video" title="Lien interne vers l&#39;article : 'Gérer la vidéo sous OpenBSD'">enregistrement vidéo</a>

- puis <a class="inside" href="/fr/sys/openbsd/tip-webcam/#enregistrement-video" title="Lien interne vers l&#39;article : 'Webcam / OpenBSD'">vérifier le support et accéder à la webcam</a>

- et pour finir l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-audio/#enregistrement-audio" title="Lien interne vers l&#39;article : 'Gestion du Son / OpenBSD'">enregistrement audio</a>
.</p>
<p>⇒ <strong>OpenBSD ≥ 6.4</strong> : Pour que la fonctionnalité WebRTC fonctionne
correctement, il faut activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-audio/#enregistrement-audio" title="Lien interne vers l&#39;article : 'Gestion du Son / OpenBSD'">enregistrement audio</a>
.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="firefox-esr-a-un-comportement-étrange">Firefox-esr a un comportement étrange</h3>
<p><strong>Si Firefox-esr a un comportement étrange</strong>, essayez de créer un
nouveau profil :</p>
<ul>
<li>soit, vous redémarrez Firefox en mode console, en utilisant l&rsquo;option
<code>-ProfileManager</code>, puis vous cliquez sur [ Create Profile ]</li>
<li>soit, vous écrivez &ldquo;about:profiles&rdquo; dans la barre d&rsquo;URL, puis vous
cliquez sur le bouton [ Créer un nouveau profile ]</li>
</ul>
<h3 id="firefox-esr-ne-démarre-pas">Firefox-esr ne démarre pas</h3>
<p><strong>Si Firefox-esr ne démarre pas</strong>, essayez de le démarrer en mode
console, avec l&rsquo;option <code>-safe-mode</code>
- <em>cela aura pour effet d&rsquo;essayer à le démarrer après avoir
désactiver toutes vos extensions, vos thèmes.</em></p>
<h3 id="firefox-esr-et-firefox-en-même-temps">Firefox-esr et Firefox en même temps</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Vous ne pouvez faire fonctionner les deux versions en même temps, si
vous n&rsquo;avez pas de profils d&rsquo;exécution différents.</div>

<p>Pour exécuter les deux versions en même temps,
<strong><a class="inside" href="/fr/sys/openbsd/firefox/" title="Lien interne vers l&#39;article : 'Firefox / OpenBSD'">Firefox</a>
</strong> et celle-ci,
vous devez créer des profils différents :</p>
<ul>
<li>Pour firefox : <code>firefox -p</code></li>
<li>Pour firefox-esr : <code>firefox-esr -p</code></li>
</ul>
<p>Il suffit de créer et d&rsquo;attribuer un profil différent…</p>
<h3 id="impression">Impression</h3>
<p>Êtes-vous sûr d&rsquo;avoir installé le paquet <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">Cups</a>

et son pendant gtk-+2 ou 3 ?!</p>
<h3 id="prefers-color-scheme">prefers-color-scheme</h3>
<p>Cette <a href="https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-color-scheme" rel="external">caractéristique de média CSS</a>
est fonctionnelle à partir de la v67.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si l&rsquo;option de <a href="/fr/sys/openbsd/firefox-esr/#aboutconfig">configuration</a> de confidentialité relative à la
prise d&rsquo;empreinte <code>privacy.resistFingerprinting</code> est paramétrée sur <code>true</code>, la
gestion de cette option ne fonctionnera pas ; ce sera le schéma <code>light</code> qui
sera choisi par défaut.</div>

<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de <strong>lire le fichier</strong>
<code>/usr/local/share/doc/pkg-readmes/firefox-esr</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le navigateur web Firefox ESR sous OpenBSD]]></summary>
        <published>2020-01-19T02:42:52+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:6e636415-3ab5-0c05-20db-66b59d73078a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/chromium/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Chromium / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Chromium" scheme="http://doc.huc.fr.eu.org/fr/tags/chromium/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://www.chromium.org/" rel="external">Chromium</a></strong> et un projet open source de
navigation qui vise à créer un moyen plus sûr, rapide et stable pour que
tous les utilisateurs d’Internet puissent utiliser le Web.</p>
<hr>
<p>Certains utilisateurs préfèrent Chromium à Google Chrome car ils jugent
inutiles ou néfastes les apports de Google Chrome par rapport à Chromium
<em>(en particulier les fonctionnalités de <del>pistage</del> télémétrie)</em>.</p>
<p>Malgré tous les défaut en terme de vie privée qu&rsquo;on peut tout de même
attribuer à cette version libérée, il reste un navigateur
<a href="https://marc.info/?l=openbsd-misc&amp;m=152872551609819&amp;w=2" rel="external">très intéressant</a>
en terme de sécurité. De plus, l&rsquo;équipe d&rsquo;OpenBSD y a ajouté des
fonctionnalités très intéressants, notamment le
<a href="/fr/sys/openbsd/chromium/#support-pledge-et-unveil">support de pledge et unveil</a>.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>chromium</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="confidentialité">Confidentialité</h3>
<p>Dirigez-vous dans les préférences de chrome puis modifiez au
<a href="https://www.c0ffee.net/blog/openbsd-on-a-laptop/#chromium" rel="external">moins les paramètres suivants</a> : <br>
<em>(utilisez la barre de recherche pour trouver facilement)</em></p>
<ul>
<li>désactivez <code>Connexion automatique</code></li>
<li>Changez le moteur de recherche par défaut pour qwant ou duckduckgo</li>
<li>désactivez <code>Utiliser un service de prédiction afin de compléter les recherches et les URL saisies dans la barre d'adresse</code></li>
<li>désactivez  <code>Utiliser un service de prédiction pour charger les pages plus rapidement</code></li>
<li>désactivez <code>Utiliser un service Web pour résoudre les erreurs de navigation</code></li>
<li>désactivez <code>Navigation sécurisée</code></li>
<li>désactivez <code>Contribuer à l'amélioration de la navigation sécurisée</code></li>
<li>désactivez <code>Envoyer une demande &quot;Interdire le suivi&quot; pendant la navigation</code>. <em>Ça ne vous rend que plus identifiable</em>.</li>
<li>désactivez <code>Me proposer de traduire les pages qui sont écrites dans une langue que je ne connais pas</code></li>
<li>désactivez <code>Afficher des notifications lorsque de nouvelles imprimantes sont détectées sur le réseau</code></li>
<li>désactivez <code>Poursuivre l'exécution des applications en arrière-plan après la fermeture de Chromium</code></li>
<li>activez <code>Bloquer les cookies tiers</code></li>
</ul>
<p>Ensuite, configurez après avoir noté dans la barre d&rsquo;URL : <code>chrome://flags</code></p>
<ul>
<li><code>UI Layout for the browser's top chrome</code> : <code>Normal</code>.</li>
<li><code>Identity consistency between browser and cookie jar</code> :  <code>Disabled</code>
<ul>
<li><em>pour éviter que Google vous connecte à un compte Chrome si vous
vous connectez à un compte Google</em>.</li>
</ul>
</li>
<li><code>SafeSearch URLs reporting</code> : <code>disabled</code></li>
</ul>
<h3 id="dark-mode">Dark Mode</h3>
<p>C&rsquo;est une fonctionnalité spécifique native à Chrome - <em>qui ne tient pas
compte des paramètres personnels de session utilisateur X</em> !</p>
<p>Nécessite v78 ≥ : Il est possible d&rsquo;activer le mode Dark en définissant
l&rsquo;URL suivante : <br>
<code>chrome://flags/#enable-force-dark</code></p>
<p>Ne pas confondre avec le mode CSS
<strong><a href="/fr/sys/openbsd/chromium/#prefers-color-scheme">prefers-color-scheme</a></strong> !</p>
<h3 id="prefers-color-scheme">prefers-color-scheme</h3>
<p>Ce mode est un mode de gestion de préférence du schéma de couleurs par
le biais de la feuille CSS. Si le site web que vous visitez propose cette
fonctionnalité, ce mode tient compte de vos préférences utilisateurs de
votre session X. C&rsquo;est &ldquo;automatique&rdquo;.</p>
<ul>
<li>Nécessite v76 ≥</li>
</ul>
<h3 id="extensions">Extensions</h3>
<p>Les extensions suivantes semblent essentielles :</p>
<ul>
<li>μblock origin</li>
<li>decentraleyes</li>
</ul>
<h4 id="keepassxc-browser">KeePassXC-Browser</h4>
<p>Depuis OpenBSD 6.6, le logiciel de confidentialité
<strong><a class="inside" href="/fr/sys/openbsd/keepassxc/" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC</a>
</strong> est installable.</p>
<p>Pour fonctionner correctement avec Chromium, il est nécessaire
d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 le
module <strong>KeePassXC-Browser</strong>.</p>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk" rel="external">https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk</a></li>
</ul>
<p>Lire la page <strong>KeePassXC</strong> pour avoir plus d&rsquo;informations concernant le
module <a class="inside" href="/fr/sys/openbsd/keepassxc/#keepassxc-browser" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC-Browser</a>
</p>
<h5 id="unveil-et-keepassxc-proxy">Unveil et KeepassXC Proxy</h5>
<p>Ajouter au <a href="/fr/sys/openbsd/chromium/#unveil">fichier de configuration unveil</a> de Chromium <code>unveil.main</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin r</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin/keepassxc-proxy rx</span>
</span></span></code></pre></div><p>Ainsi le proxy de KeePassXC pourra communiquer avec le module
KeePassXC-Browser.</p>
<h3 id="support-pledge-et-unveil">Support Pledge et Unveil</h3>
<p>Chromium sur OpenBSD est sécurisé par pledge(2) et unveil(2) - afin de
limiter les appels systèmes et les accès au système de fichier.</p>
<ul>
<li>pledge : tous les processus en bénéficient avec chromium afin de
restreindre les droits de chromium.</li>
<li>unveil : depuis OpenBSD 6.4, cette protection est activée par défaut ;
par défaut, Chromium ne pourra lire et écrire que dans le dossier de
téléchargements de l&rsquo;utilisateur.</li>
</ul>
<p>Retrouvez ces fichiers dans le répertoire <code>/etc/chromium</code> et tout particulièrement :</p>
<ul>
<li><code>/etc/chromium/pledge.main</code></li>
<li><code>/etc/chromium/unveil.main</code></li>
</ul>
<h3 id="webrtc">WebRTC</h3>
<p>Par défaut, Chromium a accès au périphérique <code>/dev/video</code>.</p>
<p>⇒ <strong>OpenBSD ≥ 6.9</strong> : Il faut aussi activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-video/" title="Lien interne vers l&#39;article : 'Gérer la vidéo sous OpenBSD'">Gérer la vidéo sous OpenBSD</a> !</p>
<p>⇒ <strong>OpenBSD ≥ 6.4</strong> : Pour que la fonctionnalité WebRTC fonctionne
correctement, il faut activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-audio/" title="Lien interne vers l&#39;article : 'Gestion du Son / OpenBSD'">Gestion du Son / OpenBSD</a>.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="protonmail">Protonmail</h3>
<p>Si votre navigateur plante lorsque vous utilisez protonmail ou une autre
bibliothèque de chiffrement javascript, définissez l&rsquo;URL <code>chrome://flags</code>
puis indiquez :</p>
<ul>
<li><code>Experimental Validate Asm.js and convert to WebAssembly when valid</code> à <code>false</code>.</li>
</ul>
<h3 id="zoom">Zoom</h3>
<p>Activez la variable d&rsquo;environnement : <code>ENABLE_WASM=1</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Chromium : navigateur web open source, sous OpenBSD]]></summary>
        <published>2020-01-19T02:22:49+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a23915b4-0a3e-1e87-156e-e7f4ced11a9b</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Utilisation du binaire fourni par le projet (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Utiliser Hugo sous OpenBSD est possible, sans soucis.</p>
<p>Il existe en tant que paquet tiers, installable par le gestionnaire de paquets : <br>
<code># pkg_add hugo</code></p>
<ul>
<li>version d&rsquo;Hugo : <strong>0.53</strong> : <code>Hugo Static Site Generator v0.53 openbsd/amd64 BuildDate: unknown</code></li>
<li>OpenBSD : <strong>6.6</strong></li>
<li>Architecture : <strong>amd64</strong></li>
</ul>
<p>Bon, maintenant soyons réaliste, cette version date d&rsquo;un an et a son lot de bogues.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Quoiqu&rsquo;il en soit le projet Hugo semble fournir pour chaque nouvelle version
des archives tar.gz qu&rsquo;il suffit de télécharger et décompresser ; il y a trois
fichiers généralement dedans, le fichier <code>LICENSE</code>, <code>README.md</code> et le binaire
<code>hugo</code>. Les archives sont à destination des architectures 32 bits <em>(donc i386)</em>,
64 bits <em>(donc amd64)</em>, et ARM.</p>
<p>Pour autant que dans votre variable d&rsquo;environnement <code>PATH</code> vous ayez inclu
<code>~/bin/</code>, il suffit de créer un lien symbolique dedans pour pouvoir utiliser ce
nouveau binaire.</p>
<p>Le propos de cet article est de &ldquo;remonter&rdquo; les différents écueils liés à ces
binaires officiels, qui parfois générent des changements dans la configuration
de Hugo, voire des dysfonctionnements.</p>
<p>La dernière version fonctionnelle est : la <strong>0.59.1</strong>.</p>
<h2 id="changements-importants">Changements importants</h2>
<h3 id="v0540">v0.54.0</h3>
<ul>
<li>version : <code>Hugo Static Site Generator v0.54.0-B1A82C61 openbsd/amd64 BuildDate: 2019-02-01T09:41:10Z</code></li>
</ul>
<p>Malheureusement, un simple <code>hugo server</code> ne fonctionne pas !</p>
<p>L&rsquo;erreur restituée : <code>Error: Error building site: EOF</code></p>
<p>Au suivant !</p>
<h3 id="v0550">v0.55.0</h3>
<ul>
<li>version : <code>Hugo Static Site Generator v0.55.0-4333CC77 openbsd/amd64 BuildDate: 2019-04-08T16:41:18Z</code></li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : cette version apporte des changements dans le fonctionnement des
<a href="/fr/web/hugo/hugo-openbsd/#shortcodes">shortcodes</a>, dans la <a href="/fr/web/hugo/hugo-openbsd/#taxonomy">taxonomie</a>
<em>(les tags, entres autres)</em>, …</div>

<h3 id="v06x">v0.6x</h3>
<p>Depuis la version 0.60.0, il y a un changement du &ldquo;moteur&rdquo; par défaut, qui est
le <strong>goldmark</strong>.</p>
<p>Cela implique de modifier le fichier de configuration pour ajouter ce qui suit,
pour le format 
































































































<span lang="en">TOML <em>(Tom&#39;s Obvious Minimal Language)</em></span>














 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">markup</span>.<span style="color:#06b6ef">goldmark</span>.<span style="color:#06b6ef">renderer</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">unsafe</span> = <span style="color:#815ba4">true</span><span style="color:#ef6155">`</span>
</span></span></code></pre></div><p><del>Il y a un <a href="https://github.com/gohugoio/hugo/issues/6553" rel="external">bogue</a> dans la
restitution du code 




























<span lang="en">HTML <em>(HyperText Markup Language)</em></span>


















































































 au sein des shortcodes.</del></p>
<h2 id="dépréciations">Dépréciations</h2>
<h3 id="pagehugo-is-deprecated">Page.Hugo is deprecated</h3>
<p>Le message suivant :</p>
<blockquote>
<p><code>Page.Hugo is deprecated and will be removed in a future release. Use the global hugo function.</code></p>
</blockquote>
<p>informe simplement que la variable <code>.Hugo</code> est obsolète, dépréciée ; il est
recommandé de la remplacer par la fonction globale <code>hugo</code>. <br>
Donc, parcourez tous vos fichiers <code>_default</code>, <code>partials</code>, voire <code>shortcodes</code> et
remplacez !</p>
<p>Voir la page <a href="https://gohugo.io/variables/hugo/" title="Lien vers la page du site officiel Hugo : Variables &gt; Hugo">Hugo Documentation : Variables &gt; Hugo</a>
</p>
<h3 id="pages-rsslink-is-deprecated">Page&rsquo;s .RSSLink is deprecated</h3>
<p>Le message suivant :</p>
<blockquote>
<p><code>Page's .RSSLink is deprecated and will be removed in a future release. Use the Output Format's link</code></p>
</blockquote>
<p>informe que la variable <code>.RSSLink</code> est osbolète et dépréciée.</p>
<p>Il est recommandé d&rsquo;utiliser le formatage de sortie , tel que : <br>
<code>{{`` with .OutputFormats.Get &quot;RSS&quot; }}{{ .RelPermalink }}{{ end }}</code></p>
<p>Voir la page <a href="https://gohugo.io/templates/output-formats/" title="Lien vers la page du site officiel Hugo : Templates &gt; Output formats">Hugo Documentation : Templates &gt; Output formats</a>
</p>
<h3 id="pages-url-is-deprecated">Page&rsquo;s .URL is deprecated</h3>
<p>Le message suivant :</p>
<blockquote>
<p><code>Page's .URL is deprecated and will be removed in a future release. Use .Permalink or .RelPermalink.</code></p>
</blockquote>
<p>explique en fait que la variable <code>.URL</code> ne doit plus être utilisée dans le corps
d&rsquo;une page. <br>
Donc, parcourez tous vos fichiers <code>_default</code>, <code>partials</code>, voire <code>shortcodes</code> et
remplacez la variable <code>.URL</code> au minimum par <code>.Permalink</code>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ne pas confondre avec la présence de la variable <code>.URL</code> qui est toujours permise
dans le contexte des menus ! <br>
<em>(cf: <a href="https://gohugo.io/variables/menus/#menu-entry-variables" title="Lien vers la page du site officiel Hugo : Variables &gt; Menus">Hugo Documentation : Variables &gt; Menus</a>
)</em></div>

<h2 id="recommandations">Recommandations</h2>
<h3 id="shortcodes">Shortcodes</h3>
<p>Il est donc recommandé de ne plus utiliser la syntaxe <code>{{``% shortcode %}}</code>
mais de lui préférer la syntaxe <code>{{``&lt; shortcode &gt;}}</code> et d&rsquo;utiliser la fonction
<code>markdownify</code>.</p>
<p>Voir la page : <a href="https://gohugo.io/functions/markdownify/" title="Lien vers la page du site officiel Hugo : Functions &gt; Markdownify">Hugo Documentation : Functions &gt; Markdownify</a>
.</p>
<h3 id="taxonomy">Taxonomy</h3>
<p>Les nœuds de taxonomies ont un nouvel accesseur nommé <code>.Page</code> qui simplifie
l&rsquo;usage aux différentes variables, telle que <code>.Titre</code>.</p>
<p>Au lieu d&rsquo;utiliser l&rsquo;ensemble suivant <code>{{ range .Data.Terms.Alphabetical }}</code>,
utilisez plutôt <code>{{ range .Site.Taxonomies.tags }}</code>.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser les différentes versions d&#39;Hugo fournies par le projet sur OpenBSD stable]]></summary>
        <published>2020-01-02T16:02:59+01:00</published>
        <updated>2020-02-25T00:30:59+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ced2cdbe-0b69-cce5-8034-22e0dabdbfed</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nextcloud/nextcloud-loop-login/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nextcloud : connexion en boucle (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <category term="login" scheme="http://doc.huc.fr.eu.org/fr/tags/login/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Par un beau matin, vous cherchez à vous connecter à votre serveur Nextcloud avec
vos identifiants.</p>
<p>Et, ce jour-là, le drame arrive : impossible de vous connecter, l&rsquo;URL est renvoyée
vers <code>login?redirect_url=/apps/files/</code> et vos identifiants sont redemandés !</p>
<p>Pas la peine de chercher dans votre configuration, si un changement est intervenu ;
ce n&rsquo;est pas non plus un problème lié à l&rsquo;authentification, voire à la
<abbr title="Two Factor Authentification">2FA</abbr>
.</p>
<h2 id="résolution">Résolution</h2>
<p><span class="red">Vérifiez</span>
 :</p>
<ul>
<li>les <strong>droits en lecture, écriture</strong> sur les répertoires :
<ul>
<li><code>netcloud</code> : <code>0750</code></li>
<li><code>cache</code> : <code>0755</code></li>
<li>et celui des sessions PHP : <code>0750</code> semble être fonctionnel, sinon <code>0755</code>.</li>
</ul>
</li>
<li>les <strong>droits utilisateurs</strong> sur les mêmes répertoires : celui de votre
utilisateur web et groupe web ; par défaut, sous OpenBSD, <code>www</code>, mais cela
peut différer selon votre système d&rsquo;exploitation, voire le service web
utilisé <em>(tel, Apache, Nginx, …)</em></li>
</ul>
<h3 id="openbsd">OpenBSD</h3>
<p>Sur OpenBSD, j&rsquo;ai remarqué un petit problème : lors de la mise à jour de PHP,
les droits sur les répertoires <code>cache</code> et <code>tmp</code> dans votre chroot
<em>(<abbr title="c'est-à-dire">càd</abbr>
 normalement : <code>/var/www</code>)</em>, ceux-ci étaient
non seulement réinitialisés pour <code>root:daemon</code>, mais aussi sur <code>0700</code> plus le
<code>sticky bit</code> activé.</p>
<p>Il semble nécessaire de les réattribuer à l&rsquo;utilisateur et au groupe web <code>www</code>,
et de remettre des droits en lecture, écriture sur <code>0755</code>.</p>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li><em><a href="https://www.ryadel.com/en/nextcloud-13-login-page-redirect-loop-how-to-fix-it/" rel="external">source</a></em></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Nextcloud : Comment résoudre le problème de connexion qui tourne en boucle…]]></summary>
        <published>2019-12-23T18:27:34+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:7ad60c11-eedd-ea1d-fcee-4663f53a5621</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/bioctl-fde/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD: Chiffrement intégral de disque dur (FDE, bioctl)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="FDE" scheme="http://doc.huc.fr.eu.org/fr/tags/fde/" />
        <category term="bioctl" scheme="http://doc.huc.fr.eu.org/fr/tags/bioctl/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le <strong>Chiffrement Intégral de Disque</strong> <em>(<strong><span lang="en">Full Disk Encryption</span></strong>,
en anglais)</em> est une opération simple à réaliser sous OpenBSD.</p>
<p>Elle nécessite l&rsquo;usage du binaire de chiffrement <code>bioctl</code> qui utilise le
sous-système <code>softraid</code> - <em>même si cela utilise le principe du RAID logiciel,
ne pas confondre avec la mise en place de RAID, qui est un processus assez
similaire, dans l&rsquo;usage de binaire et sous-système ; les deux usages cumulés
sont impossibles</em>.</p>
<p>Dans cet article, nous verrons succinctement comment chiffrer dès l&rsquo;installation
un disque entier et l&rsquo;utiliser soit avec une passphrase de sécurité, soit avec
une <a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-déverrouillage">clé USB</a>.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://www.openbsd.org/faq/faq14.html" rel="external">https://www.openbsd.org/faq/faq14.html</a> <em>(en anglais)</em></li>
<li><a href="https://wiki.obsd4a.net/openbsd.org:faq:faq14" rel="external">https://wiki.obsd4a.net/openbsd.org:faq:faq14</a></li>
<li>
<a class="man" href="https://man.openbsd.org/softraid.4" title="Page du Manuel OpenBSD pour : softraid">softraid(4)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/bioctl.8" title="Page du Manuel OpenBSD pour : bioctl">bioctl(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/fdisk.8" title="Page du Manuel OpenBSD pour : fdisk">fdisk(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/disklabel.8" title="Page du Manuel OpenBSD pour : disklabel">disklabel(8)</a>
</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Dès le démarrage du binaire d&rsquo;installation, l&rsquo;invite de commande de
l&rsquo;installateur propose le choix suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>Welcome to the OpenBSD/*** X.X installation program.
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>I<span style="color:#5bc4bf">)</span>nstall, <span style="color:#5bc4bf">(</span>U<span style="color:#5bc4bf">)</span>pgrade, <span style="color:#5bc4bf">(</span>A<span style="color:#5bc4bf">)</span>utoinstall or <span style="color:#5bc4bf">(</span>S<span style="color:#5bc4bf">)</span>hell? s
</span></span></code></pre></div><p>Il faut choisir d&rsquo;aller dans le shell ; tapez donc <kbd>s</kbd>
 puis la touche
<kbd>ENTRÉE</kbd>
.</p>
<p>En admettant que le disque principal se nomme <code>sd0</code>…</p>
<h3 id="makedev">Makedev</h3>
<p>Dans un premier temps, il nous faut nous assurer que le nœud existe réellement :</p>
<p><code>:# cd /dev &amp;&amp; sh MAKEDEV sd0</code></p>
<h3 id="urandom">urandom</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Cette étape prend un temps certain, qui dépend de la taille de votre disque dur,
mais attendez vous à patienter quelques heures…</div>

<p>Assurons-nous que le disque dur soit vierge de toutes données :</p>
<p><code>:# dd if=/dev/urandom of=/dev/rsd0c bs=1m</code></p>
<p>Ce processus remplit le disque dur dans son entier de données aléatoire. Cela
permet d&rsquo;éviter la déduction par une tierce personne de l&rsquo;espace disque réellement
utilisé.</p>
<h3 id="fdisk">fdisk</h3>
<p>Initialisons le disque dur à l&rsquo;aide de l&rsquo;outil <code>fdisk</code> :</p>
<h4 id="mbr">MBR</h4>
<p>Si vous avez démarré sur un Bios, utilisant la structure de partitionnement






















































<abbr lang="en" title="Master Boot Record">MBR</abbr>


























































, la commande sera :</p>
<p><code>:# fdisk -iy sd0</code></p>
<h4 id="gpt">GPT</h4>
<p>Par contre si vous utilisez une structure <abbr title="GUID Partition Table">GPT</abbr>
,
généralement utilisée dans le contexte d&rsquo;un Bios UEFI, mais peut aussi être
utilisée dans le contexte des BIOS &ldquo;historiques&rdquo; <em>(PC BIOS)</em>, l&rsquo;usage deviendra :</p>
<p><code>:# fdisk -iy -g -b 960 sd0</code></p>
<h3 id="disklabel">disklabel</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce n&rsquo;est pas parce que nous utilisons le formatage RAID que nous créons un RAID. <br>
Rappelez-vous, nous utilisons le sous-système <code>softraid</code> pour utiliser le binaire
<code>bioctl</code> qui permet le chiffrement du disque, excluant l&rsquo;usage d&rsquo;un RAID.</div>


<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Dans cet exemple, nous utiliserons tout l&rsquo;espace disque disponible dans une
seule partition. Il est bien sûr possible de partitionner à votre souhait… <br>
ce qui nécessitera autant de clé de chiffrement !</div>

<p>La commande <code>disklabel</code> nous sert à créer le schéma de partitionnement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># disklabel -E sd0</span>
</span></span><span style="display:flex;"><span>Label editor <span style="color:#5bc4bf">(</span>enter <span style="color:#48b685">&#39;?&#39;</span> <span style="color:#815ba4">for</span> help at any prompt<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>sd0&gt;
</span></span></code></pre></div><p>Ajoutons une partition de la taille totale, de type RAID :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>  sd0&gt; a a
</span></span><span style="display:flex;"><span>  offset: <span style="color:#5bc4bf">[</span>64<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  size: <span style="color:#5bc4bf">[</span>39825135<span style="color:#5bc4bf">]</span> *
</span></span><span style="display:flex;"><span>  FS type: <span style="color:#5bc4bf">[</span>4.2BSD<span style="color:#5bc4bf">]</span> RAID
</span></span><span style="display:flex;"><span>  sd0&gt;
</span></span></code></pre></div><p>Puis, enregistrons et quittons :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>  sd0&gt; w
</span></span><span style="display:flex;"><span>  sd0&gt; q
</span></span><span style="display:flex;"><span>  No label changes.
</span></span></code></pre></div><h3 id="bioctl">bioctl</h3>
<p>Créons le périphérique chiffré <code>sd1</code> sur la partition <code>a</code> ; nous le ferons en
utilisant le binaire <code>bioctl</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# bioctl -c C -l sd0a softraid0
</span></span><span style="display:flex;"><span>  New passphrase:
</span></span><span style="display:flex;"><span>  Re-type passphrase:
</span></span><span style="display:flex;"><span>  sd1 at scsibus2 targ <span style="color:#f99b15">1</span> lun 0: &lt;OPENBSD, SR CRYPTO, 005&gt; SCSI2 0/direct fixed
</span></span><span style="display:flex;"><span>  sd1: 19445MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">39824607</span> sectors
</span></span><span style="display:flex;"><span>  softraid0: CRYPTO volume attached as sd1
</span></span></code></pre></div><p>Nous verrons comment utiliser une <a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-déverrouillage">clé USB</a> pour
déverouiller le système au moment du démarrage en lieu et place de la
passphrase !</p>
<h4 id="makedev-1">makedev</h4>
<p>Mais dans un premier temps, il nous faut créer le nœud du périphérique <code>sd1</code> ;
répétez donc l&rsquo;étape du <a href="/fr/sys/openbsd/bioctl-fde/#makedev">makedev</a> en remplaçant par <code>sd1</code>.</p>
<h4 id="zero">zero</h4>
<p>Ensuite, il faut remplir de zéro ou de données aléatoires le premier secteur de
ce nouveau périphérique, soit :</p>
<p><code>:# dd if=/dev/zero of=/dev/rsd1c bs=1m count=1</code></p>
<p>ou par :</p>
<p><code>:# dd if=/dev/urandom of=/dev/rsd1c bs=1m count=1</code></p>
<h3 id="exit">exit</h3>
<p>Cela étant fini, il sera possible de reprendre le processus d&rsquo;installation,
après avoir écrit <code>exit</code> dans l&rsquo;invite de commande shell <em>(appelé
<span lang="en">prompt</span>, en anglais)</em></p>
<p>Lorsque le processus d&rsquo;installation demandera sur quel disque il faut installer
le système d&rsquo;exploitation, ne vous trompez pas, répondez bien <code>sd1</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>Available disks are: sd0 sd1.
</span></span><span style="display:flex;"><span>  Which disk is the root disk? <span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;?&#39;</span> <span style="color:#815ba4">for</span> details<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">[</span>sd0<span style="color:#5bc4bf">]</span> sd1
</span></span></code></pre></div><h2 id="clé-usb--déverrouillage">Clé USB : Déverrouillage</h2>
<p>Dans l&rsquo;état actuel, une fois le système d&rsquo;exploitation OpenBSD installé, lors
du démarrage, il sera demandé de taper la passphrase correspondante. <br>
Néanmoins, il est possible et intéressant de pouvoir utiliser une clé USB -
<em>ce qui est même recommandé, car celle-ci sera chiffrée elle aussi</em> - en lieu
et place !</p>
<p>Donc, après le redémarrage du système d&rsquo;exploitation, il faudra connecter la
clé USB, pour :</p>
<ul>
<li>l&rsquo;<a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-fdisk">initialiser</a>,</li>
<li>créer le <a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-disklabel">schéma de partitionnement</a> adéquat</li>
<li>puis la <a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-bioctl">chiffrer</a>.</li>
</ul>
<p>Ce processus peut normalement être fait après l&rsquo;<a href="/fr/sys/openbsd/bioctl-fde/#bioctl">usage de <code>biotcl</code></a>… <br>
il faudra adapter ce qui doit l&rsquo;être !</p>
<p>En admettant que la clé soit reconnue en tant que périphérique <code>sd2</code>…</p>
<h3 id="clé-usb--fdisk">Clé USB : fdisk</h3>
<p>Comme lors du processus d&rsquo;installation, nous utiliserons à nouveau <code>fdisk</code>, tel
que :</p>
<p><code>:# fdisk -iy sd2</code></p>
<h3 id="clé-usb--disklabel">Clé USB : disklabel</h3>
<p>Nous avons juste besoin d&rsquo;une partition de type RAID, d&rsquo;un seul Mo !</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Il est possible de spécifier la taille ainsi : <code>1024</code>, au lieu de <code>1M</code> !</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# disklabel -E sd2
</span></span><span style="display:flex;"><span>  Label editor <span style="color:#5bc4bf">(</span>enter <span style="color:#48b685">&#39;?&#39;</span> <span style="color:#815ba4">for</span> help at any prompt<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  sd0&gt; a a
</span></span><span style="display:flex;"><span>  offset: <span style="color:#5bc4bf">[</span>64<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  size: <span style="color:#5bc4bf">[</span>39825135<span style="color:#5bc4bf">]</span> 1M
</span></span><span style="display:flex;"><span>  FS type: <span style="color:#5bc4bf">[</span>4.2BSD<span style="color:#5bc4bf">]</span> RAID
</span></span><span style="display:flex;"><span>  sd0&gt; w
</span></span><span style="display:flex;"><span>  sd0&gt; q
</span></span><span style="display:flex;"><span>  No label changes.
</span></span></code></pre></div><h3 id="clé-usb--bioctl">Clé USB : bioctl</h3>
<p>Maintenant, chiffrons notre clé USB :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# bioctl -c C -k sd2a -l sd0a softraid0
</span></span><span style="display:flex;"><span>  sd3 at scsibus3 targ <span style="color:#f99b15">1</span> lun 0: &lt;OPENBSD, SR CRYPTO, 005&gt; SCSI2 0/direct fixed
</span></span><span style="display:flex;"><span>  sd3: 19445MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">39824607</span> sectors
</span></span><span style="display:flex;"><span>  softraid0: CRYPTO volume attached as sd3
</span></span></code></pre></div><p>Et voilà !</p>
<p>Il ne vous reste plus qu&rsquo;à connecter votre clé USB, pour pouvoir démarrer votre
système d&rsquo;exploitation avant le démarrage de celui-ci. La passphrase correspondante
ne vous sera pas demandée !</p>
<h3 id="clé-usb--sauvegarde">Clé USB : Sauvegarde</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION à votre fichier <code>img</code>. Ne le laissez pas à la portée de tout le monde.
<strong>Protégez-le !</strong></div>

<p>Pour sauvegarder la clé USB, en faire une image et pouvoir en créer une deuxième
ou la restaurer au besoin, nous utiliserons l&rsquo;utilitaire <code>dd</code>, tel que :</p>
<p><code>:# dd bs=8192 skip=1 if=/dev/rsd2a of=bckp-key.img</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Je vous encourage TRÈS FORTEMENT à chiffrer ce fichier .img avec GPG, puis à
détruire le fichier .img ; par exemple, sous OpenBSD :</p>
<pre tabindex="0"><code>:$ gpg2 --output bckp-key.gpg --encrypt --recipient courriel@domaine.tld bckp-key.img
:$ rm -fP bckp-key.img
</code></pre><p>Bien sûr, cela nécessite que vous ayez créer une clé GPG pour votre courriel !</p>
</div>

<h3 id="clé-usb--restauration">Clé USB : Restauration</h3>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si vous avez suivi ma recommandation de chiffrer avec GPG votre sauvegarde ; il
vous faudra utiliser GPG pour déchiffrer le fichier GPG avant la restauration,
tel que : <br>
<code>gpg2 --output bckp-key.img --decrypt bckp-key.gpg</code></div>

<p>Pour la restaurer, il faudra utiliser <code>dd</code>, tel que :</p>
<p><code>:# dd bs=8192 seek=1 if=bckp-key.img of=/dev/rsd2a</code></p>
<h3 id="clé-usb--copie">Clé USB : Copie</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne laissez pas traîner votre clé de secours n&rsquo;importe où ! <br>
Rangez-la dans un endroit évident pour vous, seulement vous…</div>

<p>Pour créer une nouvelle clé USB de secours, il faudra :</p>
<ul>
<li>l&rsquo;<a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-fdisk">initialiser</a>,</li>
<li><a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-disklabel">créer la table de partitionnement</a>,</li>
<li>et copier la sauvegarde comme si c&rsquo;était une <a href="/fr/sys/openbsd/bioctl-fde/#clé-usb-restauration">restauration</a>.</li>
</ul>
<h2 id="documentations-tierces">Documentations tierces</h2>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Master_boot_record" title="Article Wikipédia : Master_boot_record">Master_boot_record <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://fr.wikipedia.org/wiki/GUID_Partition_Table" title="Article Wikipédia : GUID_Partition_Table">GUID_Partition_Table <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mise en place d&#39;un chiffrement intégral de disque dur lors de l&#39;installation d&#39;OpenBSD, avec gestion de passphrase ou mieux d&#39;une clé USB de déverouillage.]]></summary>
        <published>2019-12-22T12:59:26+01:00</published>
        <updated>2020-01-08T18:55:00+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f843c77f-46a8-5d43-ebe3-923ff0704ece</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-menu-nav/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Menu de navigation (simple ou dropdown)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="Menu" scheme="http://doc.huc.fr.eu.org/fr/tags/menu/" />
        <category term="nav" scheme="http://doc.huc.fr.eu.org/fr/tags/nav/" />
        <category term="dropdown" scheme="http://doc.huc.fr.eu.org/fr/tags/dropdown/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Le but de cet article est de montrer comment créer un menu de navigation pour
le <abbr title="Static Site Generator">SSG</abbr>
 qu&rsquo;est Hugo.</p>
<p>Nous verrons deux manières différentes pour créer :</p>
<ul>
<li>un <a href="/fr/web/hugo/hugo-menu-nav/#menu-simple">menu simple</a></li>
<li>un menu de type <a href="/fr/web/hugo/hugo-menu-nav/#menu-dropdown">dropdown</a></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Hugo ne sait pas générer dynamiquement les menus. En conséquence, il faut tout
remplir à la main, et bien faire attention à ce qui est rempli !</div>

<h2 id="documentation">Documentation</h2>
<p>La documentation officielle en anglais :</p>
<ul>
<li><a href="https://gohugo.io/getting-started/configuration/" title="Lien vers la page du site officiel Hugo : Getting started &gt; Configuration">Hugo Documentation : Getting started &gt; Configuration</a>
</li>
<li><a href="https://gohugo.io/variables/menus/" title="Lien vers la page du site officiel Hugo : Variables &gt; Menus">Hugo Documentation : Variables &gt; Menus</a>
,</li>
<li><a href="https://gohugo.io/content-management/menus/" title="Lien vers la page du site officiel Hugo : Content management &gt; Menus">Hugo Documentation : Content management &gt; Menus</a>
,</li>
<li><a href="https://gohugo.io/templates/menu-templates/" title="Lien vers la page du site officiel Hugo : Templates &gt; Menu templates">Hugo Documentation : Templates &gt; Menu templates</a>
,</li>
<li><a href="https://gohugo.io/content-management/organization/#index-pages--indexmd" title="Lien vers la page du site officiel Hugo : Content management &gt; Organization">Hugo Documentation : Content management &gt; Organization</a>
</li>
<li><a href="https://gohugo.io/content-management/front-matter/" title="Lien vers la page du site officiel Hugo : Content management &gt; Front matter">Hugo Documentation : Content management &gt; Front matter</a>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Les différentes entrées du menu sont écrites dans le fichier de configuration
<code>config.toml</code>. <em>Pour information, il existe deux autres formats, JSON et YAML</em>.
Nous partirons, du prédicat, d&rsquo;un site n&rsquo;ayant qu&rsquo;une seule langue. Si la
conception d&rsquo;un menu multilangue est subtilement différente, le fonctionnement
reste exactement le même.</p>
<ul>
<li>Un site <a href="/fr/web/hugo/hugo-menu-nav/#monolangue">monolangue</a> se configure par le biais de l&rsquo;entrée : <code>menu</code></li>
<li>Là, où un site <a href="/fr/web/hugo/hugo-menu-nav/#multilangue">multilangue</a> se configure par l&rsquo;entrée : <code>languages</code></li>
</ul>
<p>Par défaut, Hugo génére un site pour la langue anglaise ; pour le paramètrer
dans votre langue native, il faut modifier au moins la variable
<code>defaultContentLanguage</code>, par exemple pour la langue française : <br>
<code>defaultContentLanguage = &quot;fr&quot;</code>, qui peut agrémentée de la variable
<code>languageCode = &quot;fr-FR&quot;</code>.</p>
<p>Généralement, le fichier <abbr title="HyperText Markup Language">HTML</abbr>
 sera
crée dans le répertoire <code>layouts/partials/</code>, et quelque soit son nom,
<em>pour l&rsquo;exemple, nous l&rsquo;appelerons <code>nav.html</code> par soucis de simplicité</em>, il
sera appelé depuis le fichier <code>layouts/_default/baseof.html</code>.</p>
<p><code>{{ partial &quot;nav.html&quot; . }}</code></p>
<h3 id="menu-simple">Menu simple</h3>
<p>C&rsquo;est typiquement le genre de menu qui renvoie vers des éléments au sein de la
page, mais il est possible de renvoyer vers une page nommée.</p>
<p>Pour exemple : <a href="http://huc.fr.eu.org" rel="external">http://huc.fr.eu.org</a></p>
<h4 id="monolangue">Monolangue</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">menu</span>]
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;who&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Qui&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#whoiam&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;act&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Quoi&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#projects&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">3</span>
</span></span></code></pre></div><p>On remarque donc la présence de variables strictement nécessaires :</p>
<ul>
<li><code>identifier</code> : un identifiant, strictement nécessaire et unique à chaque entrée</li>
<li><code>name</code> : le nom</li>
<li><code>url</code> : le nom de l&rsquo;ancre, ou de la page, à cibler. La présence du symbole <code>#</code>
signifie que le lien ciblé est une ancre dans la page ; son absence cible
un article précisément nommé.</li>
</ul>
<p>Ainsi que de certaines utiles :</p>
<ul>
<li><code>weight</code> : c&rsquo;est le poids du lien dans le menu, plus le poids est faible,
plus le lien est &ldquo;important&rdquo;.</li>
<li><code>pre</code> : permet d&rsquo;injecter du code avant le texte.</li>
<li><code>post</code> : permet d&rsquo;injecter du code après le texte - <em>n&rsquo;est pas présentée ici</em></li>
</ul>
<p>Le reste, sachant qu&rsquo;il existe d&rsquo;autres variables, je vous renvoie à la
documentation officielle.</p>
<h4 id="multilangue">Multilangue</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">languages</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">en</span>]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">homeText</span> = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">languageName</span> = <span style="color:#48b685">&#34;English&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span> = <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">en</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;who&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Who I am&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#whoiam&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">en</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;act&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Projects&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#projects&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">en</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">fr</span>]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">homeText</span> = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">languageName</span> = <span style="color:#48b685">&#34;Français&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span> = <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">fr</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;who&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Qui&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#whoiam&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">fr</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;act&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Quoi&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#projects&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">languages</span>.<span style="color:#06b6ef">fr</span>.<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;#contact&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">3</span>
</span></span></code></pre></div><p>Bien-sûr, allez lire la documentation officielle !</p>
<h4 id="structure">Structure</h4>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Cette structure de répertoire n&rsquo;est pas du tout nécessaire si vous ne faites
qu&rsquo;un site monopage, telle juste une page d&rsquo;accueil, et des liens vers des ancres !</div>

<p>Admettons que vous voulez diriger vers des pages, et non pas des ancres… il vous
faudra donc créer dans le répertoire <code>content</code> les articles correspondants portant
les noms servant de valeur à la variable <code>url</code>.</p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>content/
</span></span><span style="display:flex;"><span>    contact.md
</span></span><span style="display:flex;"><span>    projects.md
</span></span><span style="display:flex;"><span>    whoiam.md
</span></span></code></pre></div><p>Bien sûr, il est possible de mixer liens vers des pages et des ancres. À vous
de modifier en conséquence…</p>
<h4 id="html">HTML</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-border&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;container&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">nav</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav justify-content-center&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    {{ range .Site.Menus.main }}
</span></span><span style="display:flex;"><span>    {{ $text := print .Name | safeHTML }}
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-link&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .URL }}&#34;</span>&gt;{{ $text }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span>    {{ end }}
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#5bc4bf">nav</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><p>On parcourt tout simplement l&rsquo;ensemble de la variable <code>.Site.Menus.main</code> pour
restituer le code correspondant.</p>
<p>Maintenant si dans le fichier de configuration, vous ajoutez et remplissez la
variable <code>pre</code>, il vous faudra modifier le fichier HTML ainsi, par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $icon := printf &#34;&lt;<span style="color:#5bc4bf">i</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">\&#34;%s\&#34;</span>&gt;&lt;/<span style="color:#5bc4bf">i</span>&gt;&#34; .Pre }}
</span></span><span style="display:flex;"><span>{{ $text := print $icon &#34; &#34; .Name | safeHTML }}
</span></span></code></pre></div><p>Cet exemple nous permet d&rsquo;injecter du code HTML afin d&rsquo;ajouter une icône avant
le texte, ce qui est utile dans le contexte de la bibliothèque <strong>Font Awesome</strong>
ou de toute autre semblable.</p>
<h3 id="menu-dropdown">Menu dropdown</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Hugo n&rsquo;est pour l&rsquo;instant capable de gérer qu&rsquo;un sous-niveau de menu !</div>

<p>Pour obtenir un menu dropdown, tel que vous voyez
<a href="/fr/web/hugo/hugo-menu-nav/#page-top">en haut de page sur ce site</a>, le plus simple est d&rsquo;utiliser le
framework <a href="https://getbootstrap.com/" rel="external">Bootstrap</a>.</p>
<p>En tenant compte du fait que vous savez intégrer la bibliothèque













































<span lang="en">JS <em>(JavaScript)</em></span>


































































 et la feuille 










<span lang="en">CSS <em>(Cascade Style Sheet)</em></span>




































































































…</p>
<h4 id="structure-1">Structure</h4>
<p>Dans le répertoire <code>content</code>, il est nécessaire :</p>
<ul>
<li>de créer un ou plusieurs sous-répertoires, qui correspondront aux <code>sections</code></li>
<li>de créer un ou plusieurs répertoires enfants, dans ces premiers sous-répertoires,
qui correspondront aux <code>sous-sections</code></li>
</ul>
<p>Voici un exemple de structure de répertoires :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>content/
</span></span><span style="display:flex;"><span>    dev/
</span></span><span style="display:flex;"><span>        _index.md
</span></span><span style="display:flex;"><span>        javascript/
</span></span><span style="display:flex;"><span>            _index.md
</span></span><span style="display:flex;"><span>            article.md
</span></span><span style="display:flex;"><span>        python/
</span></span><span style="display:flex;"><span>            _index.md
</span></span><span style="display:flex;"><span>            article.md
</span></span><span style="display:flex;"><span>        shell/
</span></span><span style="display:flex;"><span>            _index.md
</span></span><span style="display:flex;"><span>            article1.md
</span></span><span style="display:flex;"><span>            article2.md
</span></span><span style="display:flex;"><span>            article3.md
</span></span></code></pre></div><p>On remarque la présence de fichier <code>_index.md</code> dans chaque répertoire. Le nom
des fichiers <code>article*.md</code> n&rsquo;a pas d&rsquo;importance.</p>
<p>De même le nom des répertoires importe peu en soit, par contre veillez bien à
la correspondance avec la variable <code>url</code> dans le fichier de configuration.</p>
<h4 id="fichier-_indexmd">Fichier <code>_index.md</code></h4>
<p>Chaque répertoire a son propre fichier <code>_index.md</code> dont le but est simplement
d&rsquo;activer le répertoire qui doit comporter à minima le
<span lang="en">Front Matter</span>, au format 














































































































<span lang="en">YAML <em>(YAML Ain&#39;t Markup Language)</em></span>
, qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#fec418">---</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">title</span>: <span style="color:#48b685">&#34;Title&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">date</span>: <span style="color:#48b685">2019-11-28T23:40:14</span><span style="color:#f99b15">+01</span>:<span style="color:#f99b15">00</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">draft</span>: <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span><span style="color:#fec418">---</span>
</span></span></code></pre></div><p>Si vous voulez qu&rsquo;il ne soit pas indexé, rajouter la variable <code>noindex: true</code>.
<em>(ce qui est évidemment utile dans le contexte de génération de
<a class="inside" href="/fr/web/hugo/hugo-feed/" title="Lien interne vers l&#39;article : 'Hugo : Feed Atom, JSON, RSS'">flux de syndication</a>
)</em>.</p>
<h4 id="fichier-configtoml">Fichier <code>config.toml</code></h4>
<p>La structure du fichier de configuration est sensiblement la même !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">menu</span>]
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;dev&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Développement&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;dev&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;shell&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Shell&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">parent</span>      = <span style="color:#48b685">&#34;dev&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;shell&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">10</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;js&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;JavaScript&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">parent</span>      = <span style="color:#48b685">&#34;dev&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;javascript&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>    [[<span style="color:#06b6ef">menu</span>.<span style="color:#06b6ef">main</span>]]
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">identifier</span>  = <span style="color:#48b685">&#34;py&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name</span>        = <span style="color:#48b685">&#34;Python&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">parent</span>      = <span style="color:#48b685">&#34;dev&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">pre</span>        = <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">url</span>         = <span style="color:#48b685">&#34;python&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">weight</span>     = <span style="color:#f99b15">12</span>
</span></span></code></pre></div><p>On remarque tout particulièrement :</p>
<ul>
<li>la présence des variables <code>parent</code> qui permettent de définir que l&rsquo;entrée de
menu en question a pour parent celui qui porte l&rsquo;identifiant nommé. <br>
Dans cet exemple, elles ont pour valeur <code>dev</code> et renvoie à l&rsquo;entrée de menu
qui a <code>identifier = &quot;dev&quot;</code>, <em>qui est bien aussi leur répertoire parent,
dans la <a href="/fr/web/hugo/hugo-menu-nav/#structure">structure de répertoires</a></em>.</li>
</ul>
<p>Si vous avez un site <a href="/fr/web/hugo/hugo-menu-nav/#multilangue">multilangue</a>, il faudra adapter l&rsquo;exemple
ci-dessus pour le faire correspondre…</p>
<h4 id="html-1">HTML</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#776e71">&lt;!-- Navbar --&gt;</span>
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">nav</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar navbar-expand-lg navbar-transparent&#34;</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;container&#34;</span>&gt;
</span></span><span style="display:flex;"><span>            &lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-translate&#34;</span>&gt;
</span></span><span style="display:flex;"><span>                &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-brand&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ relLangURL &#34;</span><span style="color:#ef6155">/&#34;</span> <span style="color:#ef6155">}}&#34;</span> <span style="color:#06b6ef">rel</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;tooltip&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{.Site.Title}}&#34;</span> <span style="color:#06b6ef">data-placement</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;bottom&#34;</span>&gt;
</span></span><span style="display:flex;"><span>                    {{.Site.Title}}
</span></span><span style="display:flex;"><span>                &lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span>                &lt;<span style="color:#5bc4bf">button</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-toggler navbar-toggler&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;button&#34;</span> <span style="color:#06b6ef">data-toggle</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;collapse&#34;</span> <span style="color:#06b6ef">data-target</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;#navigation&#34;</span> <span style="color:#06b6ef">aria-controls</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navigation-index&#34;</span> <span style="color:#06b6ef">aria-expanded</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;false&#34;</span> <span style="color:#06b6ef">aria-label</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Toggle navigation&#34;</span>&gt;
</span></span><span style="display:flex;"><span>                    &lt;<span style="color:#5bc4bf">span</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-toggler-bar bar1&#34;</span>&gt;&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>                    &lt;<span style="color:#5bc4bf">span</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-toggler-bar bar2&#34;</span>&gt;&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>                    &lt;<span style="color:#5bc4bf">span</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-toggler-bar bar3&#34;</span>&gt;&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>                &lt;/<span style="color:#5bc4bf">button</span>&gt;
</span></span><span style="display:flex;"><span>            &lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span><span style="display:flex;"><span>            &lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;collapse navbar-collapse justify-content-end&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navigation&#34;</span>&gt;
</span></span><span style="display:flex;"><span>              &lt;<span style="color:#5bc4bf">ul</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;navbar-nav ml-auto&#34;</span>&gt;
</span></span><span style="display:flex;"><span>      {{ range .Site.Menus.main }}
</span></span><span style="display:flex;"><span>        {{ if .HasChildren }} {{ $id := print &#34;navbarDropdownMenuLink&#34; .Identifier }}
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#5bc4bf">li</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-item dropdown&#34;</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;#&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-link dropdown-toggle&#34;</span>  <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $id }}&#34;</span> <span style="color:#06b6ef">data-toggle</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;dropdown&#34;</span>&gt;
</span></span><span style="display:flex;"><span>            {{ .Pre }} &lt;<span style="color:#5bc4bf">span</span>&gt;{{ .Name }}&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>            &lt;<span style="color:#5bc4bf">span</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;caret&#34;</span>&gt;&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;dropdown-menu dropdown-menu-right&#34;</span> <span style="color:#06b6ef">aria-labelledby</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $id }}&#34;</span>&gt;
</span></span><span style="display:flex;"><span>            {{ range .Children }}
</span></span><span style="display:flex;"><span>            &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;dropdown-item&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .URL | relLangURL }}&#34;</span><span style="color:#ef6155">{{</span> <span style="color:#06b6ef">if</span> <span style="color:#ef6155">$.</span><span style="color:#06b6ef">IsHome</span> <span style="color:#ef6155">}}</span> <span style="color:#06b6ef">data-target</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .URL }}&#34;</span><span style="color:#ef6155">{{</span> <span style="color:#06b6ef">end</span> <span style="color:#ef6155">}}</span>&gt;{{ .Name }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span>            {{end}}
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#5bc4bf">li</span>&gt;
</span></span><span style="display:flex;"><span>        {{ else }}
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#5bc4bf">li</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-item&#34;</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nav-link&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .URL | relLangURL }}&#34;</span><span style="color:#ef6155">{{</span> <span style="color:#06b6ef">if</span> <span style="color:#ef6155">$.</span><span style="color:#06b6ef">IsHome</span> <span style="color:#ef6155">}}</span> <span style="color:#06b6ef">data-target</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .URL }}&#34;</span><span style="color:#ef6155">{{</span> <span style="color:#06b6ef">end</span> <span style="color:#ef6155">}}</span>&gt;{{ .Name }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#5bc4bf">li</span>&gt;
</span></span><span style="display:flex;"><span>        {{ end }}
</span></span><span style="display:flex;"><span>      {{ end }}
</span></span><span style="display:flex;"><span>                &lt;/<span style="color:#5bc4bf">ul</span>&gt;
</span></span><span style="display:flex;"><span>            &lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#5bc4bf">nav</span>&gt;
</span></span><span style="display:flex;"><span><span style="color:#776e71">&lt;!-- End Navbar --&gt;</span>
</span></span></code></pre></div><h2 id="clap-de-fin">Clap de Fin</h2>
<p>&ldquo;Voilà, c&rsquo;est fini !&rdquo;</p>
<p>Nous avons ainsi vu comment créer un menu simple ou un menu dropdown pour Hugo.</p>
<p>N&rsquo;oubliez pas de vous amuser, puis de publier vos articles, et si besoin de vous
faire aider par la <a href="https://discourse.gohugo.io/" rel="external">communauté anglaise de Hugo</a>.</p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment créer un menu de navigation simple, ou plus complexe, de type dropdown pour Hugo]]></summary>
        <published>2019-12-18T11:38:00+01:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0ffabda9-ad32-4abd-b230-a6f87a35ca33</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-feed/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Feed Atom, JSON, RSS</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="Feed" scheme="http://doc.huc.fr.eu.org/fr/tags/feed/" />
        <category term="RSS" scheme="http://doc.huc.fr.eu.org/fr/tags/rss/" />
        <category term="Atom" scheme="http://doc.huc.fr.eu.org/fr/tags/atom/" />
        <category term="JSON" scheme="http://doc.huc.fr.eu.org/fr/tags/json/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Parmi les flux de données, <a class="tag" href="/fr/tags/hugo">Hugo</a>
 est capable de créer plusieurs
flux dont 
















































































<span lang="en">RSS <em>(Really Simple Syndication)</em></span>






























 <em>(actuellement, à la norme 2.0)</em>.</p>
<p><strong>Hugo</strong> est donc capable de générer un flux <a href="/fr/web/hugo/hugo-feed/#rss">RSS</a>, ou de type <a href="/fr/web/hugo/hugo-feed/#json">JSON</a>,
mais pas <a href="/fr/web/hugo/hugo-feed/#atom">ATOM</a> - <em>pour ce dernier, nous verrons comment faire dans le
chapitre ad hoc</em>.</p>
<h2 id="documentation">Documentation</h2>
<p>Un petit tour sur la documentation officielle Hugo :</p>
<ul>
<li><a href="https://gohugo.io/templates/rss/" title="Lien vers la page du site officiel Hugo : Templates &gt; Rss">Hugo Documentation : Templates &gt; Rss</a>
</li>
<li><a href="https://gohugo.io/templates/output-formats/" title="Lien vers la page du site officiel Hugo : Templates &gt; Output formats">Hugo Documentation : Templates &gt; Output formats</a>
</li>
<li><a href="https://gohugo.io/variables/site/#site-variables-list" title="Lien vers la page du site officiel Hugo : Variables &gt; Site">Hugo Documentation : Variables &gt; Site</a>
</li>
<li><a href="https://gohugo.io/variables/hugo/" title="Lien vers la page du site officiel Hugo : Variables &gt; Hugo">Hugo Documentation : Variables &gt; Hugo</a>
</li>
<li><a href="https://gohugo.io/functions/sha/" title="Lien vers la page du site officiel Hugo : Functions &gt; Sha">Hugo Documentation : Functions &gt; Sha</a>
</li>
<li><a href="https://gohugo.io/functions/range/" title="Lien vers la page du site officiel Hugo : Functions &gt; Range">Hugo Documentation : Functions &gt; Range</a>
</li>
</ul>
<h2 id="détails-techniques">Détails Techniques</h2>
<p>Commençons par les détails techniques suivants à-propos de la gestion de
différents éléments ; chaque format de flux a ses propres spécificités,
certaines sont communes ou peuvent se ressembler. <br>
Merci de lire les [RFC](#documentations tierces) adéquates.</p>
<h3 id="author">author</h3>
<p>Les trois formats de flux gérent un élément <code>author</code> dans les différentes
entrées générées. Quant à l&rsquo;auteur du site, là où ATOM et 













































<span lang="en">JSON <em>(JavaScript Object Notation)</em></span>


































































ont leur élément <code>author</code> avec leurs spécificités, 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 a son
propre élément <code>managingEditor</code>, voire <code>webMaster</code>.</p>
<p>Il faut configurer le bloc <code>author</code> dans le fichier de configuration,
de telle manière :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">params</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">params</span>.<span style="color:#06b6ef">author</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">email</span> = <span style="color:#48b685">&#34;courriel@domaine.tld&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name</span>  = <span style="color:#48b685">&#34;Nom Prénom&#34;</span>
</span></span></code></pre></div><h3 id="category">category</h3>
<p>Là où ATOM et 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 sont capables de générer un élément <code>catégory</code>,















































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 utilise l&rsquo;élément <code>tag</code>.</p>
<p>Dans tous les cas, j&rsquo;ai utilisé la taxonomie des tags pour les créer.</p>
<p>Il faut configurer la taxonomie dans le fichier de configuration, de
telle manière :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">taxonomies</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">tag</span> = <span style="color:#48b685">&#34;tags&#34;</span>
</span></span></code></pre></div><h3 id="copyright">copyright</h3>
<p>Là où 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 a son élément <code>copyright</code>,</p>
<ul>
<li>ATOM peut annoncer par le biais d&rsquo;un élément <code>link</code> qui permet de
cibler un fichier de licence - <em>telle une licence 







<span lang="en">CC <em>(Creatives Commons)</em></span>







































































































</em> -
ainsi que son élément <code>rights</code>.</li>
<li>














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 n&rsquo;a rien de prévu.</li>
</ul>
<p>Il faut configurer la variable <code>copyright</code> dans le fichier de configuration.</p>
<h3 id="description-1">description</h3>
<p>Là où 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 et 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 ont leur élément <code>description</code> du
flux, ATOM n&rsquo;en a pas, mais il est possible d&rsquo;utiliser l&rsquo;élément <code>subtitle</code>.</p>
<p>Concernant l&rsquo;usage de l&rsquo;élément <code>description</code>, j&rsquo;utilise personnellement
la variable <code>site.Params.description</code>.</p>
<p>Il faut configurer la variable <code>description</code> dans le fichier de configuration.</p>
<h3 id="generator">generator</h3>
<p>Seul ATOM et 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 sont capables de générer un élément <code>generator</code>,
bien qu&rsquo;ATOM le fasse plus finement.</p>
<p>On peut utiliser les variables spécifiques à Hugo.</p>
<h3 id="id">id</h3>
<p>Pour 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























, l&rsquo;identifiant d&rsquo;une entrée est l&rsquo;élément <code>guid</code>. <br>
ATOM et 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 ont un élément <code>id</code>. ATOM a aussi son identifiant de
site.</p>
<p>Il est important de veiller à ce que cet identifiant soit unique ; il y
a plusieurs manières de les générer :</p>
<ul>
<li>
<p>Soit tout simplement par le biais de l&rsquo;







































































































<span lang="en">URL <em>(Uniform Resource Locator)</em></span>







 du site, ou de
l&rsquo;article correspondant à l&rsquo;entrée : <br>
<code>&lt;id&gt;{{ .Permalink }}&lt;/id&gt;</code></p>
</li>
<li>
<p>Soit en utilisant le schéma de notation <code>tag</code>, définie par la 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>


































































4151, de type <code>tag:identifiant,DATE:alphanumerique</code> et où <code>tag:identifiant,DATE</code>
ne doit pas changer sur l&rsquo;ensemble du site, seule la partie <code>alphanumerique</code>
sera l&rsquo;objet de l&rsquo;unicité de l&rsquo;article ou de l&rsquo;identifiant du site :</p>
<ul>
<li>
<p>où l&rsquo;identifiant peut être soit une adresse mail, soit le nom de
domaine ; ce dernier semble être la préférence.</p>
</li>
<li>
<p>où DATE doit correspondre à la norme 










































<span lang="en">ISO <em>(International Organization for Standardization)</em></span>




































































 8601, à minima
l&rsquo;année, codée sur 4 chiffres, telle que <code>2019</code> ; la préférence peut
être donnée à la forme <code>YYYY-MM-DD</code> où l&rsquo;année, le mois et le jour
sont séparés par un tiret <code>-</code>, telle que <code>2019-10-07</code> qui peut
correspondre à la date de création de votre domaine, par exemple.</p>
</li>
<li>
<p>où <code>alphanumerique</code> est un ensemble de lettres et de chiffres.</p>
</li>
<li>
<p>Pour exemple :</p>
<ul>
<li>
<p>Pour l&rsquo;identifiant du site :
<code>{{ $url := urls.Parse .Permalink }}{{ $id := print &quot;tag:&quot; $url.Host &quot;,2019-10-07:&quot; }}&lt;id&gt;{{ $id }}website&lt;/id&gt;</code></p>
</li>
<li>
<p>Pour l&rsquo;identifiant d&rsquo;entrée :
<code>&lt;id&gt;{{ $id }}{{ anchorize .RelPermalink }}&lt;/id&gt;</code></p>
</li>
<li>
<p>Pour 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























, remplacez la balise <code>&lt;id&gt;</code> par <code>&lt;guid&gt;</code>.
De même, si vous utilisez la notation par tag ou par UURI,
il vous faudra ajouter l&rsquo;attribut <code>isPermalink</code>, tel que :
<code>isPermaLink=&quot;false&quot;</code></p>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Soit en utilisant le schéma de notation <code>UURI</code> définie par la 















































































<span lang="en">RFC <em>(Requests for comments)</em></span>
































4122 - <em>qui est humainement incompréhensible</em> ; l&rsquo;avantage avec Hugo est
qu&rsquo;on peut la générer dynamiquement en utilisant la fonction <code>sha</code>, tout
particulièrement <code>sha1</code> conforme à la version 5 de ladite numérotation,
telle que :</p>
</li>
</ul>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{ $uuid := sha1 .Permalink }}&lt;id&gt;urn:uuid:{{substr $uuid 0 8}}-{{substr $uuid 10 4}}-{{substr $uuid 15 4}}-{{substr $uuid 20 4}}-{{substr $uuid 25 12}}&lt;/id&gt;
</code></pre><h3 id="image">image</h3>
<p>Là où 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 gère l&rsquo;élément <code>image</code> pour afficher le logo,</p>
<ul>
<li>
<p>ATOM et 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 gèrent deux éléments différents, <code>icon</code> pour
l&rsquo;image de favicon, et <code>logo</code> pour votre… logo !</p>
</li>
<li>
<p>














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 est capable, en plus, de gérer un avatar pour l&rsquo;auteur.</p>
</li>
</ul>
<h3 id="limite">Limite</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il semble nécessaire d&rsquo;utiliser au moins Hugo v0.55.x</div>

<p>Le code Hugo suivant, <em>que j&rsquo;utilise dans chacun des modèles</em>, permet de
limiter le nombre d&rsquo;entrées selon :</p>
<ul>
<li>
<p>La limite du service 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























,</p>
</li>
<li>
<p>Si les pages ont le paramètre <code>disable_feed</code> sur <code>true</code>, elles ne sont
pas incluses.</p>
</li>
<li>
<p>On capture le nombre de pages,</p>
</li>
<li>
<p>Puis on utilise la fonction Hugo <code>range</code> pour générer dynamiquement le
nombre d&rsquo;entrées - <em>l&rsquo;usage de la fonction dans le modèle pour 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>


































































différe légérement de celui pour les modèles ATOM et 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























</em> - :</p>
</li>
</ul>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
{{- $pages := where site.RegularPages &#34;.Params.disable_feed&#34; &#34;!=&#34; true -}}
{{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
</code></pre><h2 id="configuration">Configuration</h2>
<ul>
<li>Le fichier de configuration principal : <code>config.toml</code></li>
</ul>
<h3 id="rss">RSS</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Il est possible de spécifier dans le fichier de configuration le format de
sortie</p>
<p><abbr lang="en" title="Really Simple Syndication">RSS</abbr></p>
<p>pour <code>home</code>, <code>section</code> et les deux <code>taxonomy</code>,
<code>taxonomyTerm</code>.</p>
</div>

<p>Personnellement, je renomme le nom du flux 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























 en modifiant dans
le fichier de configuration, la variable <code>baseName</code> à <code>rss</code> parce que je ne
pense pas que celui-ci doit porter le nom <code>index</code>.</p>
<p>En effet, le nom <code>rss.xml</code> est plus parlant !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;RSS&#34;</span>]
</span></span><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">RSS</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;rss&#34;</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Sachez qu&rsquo;il est possible de surcharger la génération native du flux</p>
<p><abbr lang="en" title="Really Simple Syndication">RSS</abbr></p>
<p>, en créant un modèle dans <code>_default</code>.</p>
</div>

<h4 id="rsstemplate">RSS:Template</h4>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il n&rsquo;est pas nécessaire de créer ce modèle du fait que Hugo génére correctement,
mais pour de l&rsquo;anglais, le fichier</p>
<p><abbr lang="en" title="Really Simple Syndication">RSS</abbr></p>
<p>, nommé <code>index.xml</code>.</p>
</div>

<p>J&rsquo;ai créé mon propre modèle, tenant compte du fait d&rsquo;être multilangue.</p>
<hr>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>{{ printf `<span style="color:#776e71">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; standalone=&#34;yes&#34; ?&gt;</span>` | safeHTML }}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;rss</span> <span style="color:#06b6ef">version=</span><span style="color:#48b685">&#34;2.0&#34;</span> <span style="color:#06b6ef">xmlns:atom=</span><span style="color:#48b685">&#34;http://www.w3.org/2005/Atom&#34;</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;channel&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;title&gt;</span>{{ if eq .Title  site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T &#34;on&#34; }}{{ end }}&#39;{{ site.Title }}&#39;{{ end }}<span style="color:#5bc4bf">&lt;/title&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;link&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/link&gt;</span>
</span></span><span style="display:flex;"><span>    {{ with site.Params.description -}}<span style="color:#5bc4bf">&lt;description&gt;</span>{{ . }}<span style="color:#5bc4bf">&lt;/description&gt;</span>{{- end }}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;docs&gt;</span>http://blogs.law.harvard.edu/tech/rss<span style="color:#5bc4bf">&lt;/docs&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;generator&gt;</span>Hugo {{ Hugo.Version }}<span style="color:#5bc4bf">&lt;/generator&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;image&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;description&gt;</span>Logo<span style="color:#5bc4bf">&lt;/description&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;height&gt;</span>128<span style="color:#5bc4bf">&lt;/height&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;link&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/link&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;title&gt;</span>{{ if eq  .Title  site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T &#34;on&#34; }}{{ end }}&#39;{{ site.Title }}&#39;{{ end }}<span style="color:#5bc4bf">&lt;/title&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;url&gt;</span>{{ site.BaseURL }}img/Logo.png<span style="color:#5bc4bf">&lt;/url&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;width&gt;</span>128<span style="color:#5bc4bf">&lt;/width&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;/image&gt;</span>
</span></span><span style="display:flex;"><span>    {{ with site.LanguageCode }}<span style="color:#5bc4bf">&lt;language&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/language&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    {{ with site.Params.author.email }}<span style="color:#5bc4bf">&lt;managingEditor&gt;</span>{{.}}{{ with site.Params.author.name }} ({{.}}){{end}}<span style="color:#5bc4bf">&lt;/managingEditor&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;webMaster&gt;</span>{{.}}{{ with site.Author.name }} ({{.}}){{end}}<span style="color:#5bc4bf">&lt;/webMaster&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    {{ with site.Copyright }}<span style="color:#5bc4bf">&lt;copyright&gt;</span>© {{ $.Date.Format &#34;2006&#34; | safeHTML }} {{ site.Author.name }}; {{.}}<span style="color:#5bc4bf">&lt;/copyright&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    {{ if not .Date.IsZero }}<span style="color:#5bc4bf">&lt;lastBuildDate&gt;</span>{{ .Date.Format &#34;Mon, 02 Jan 2006 15:04:05 -0700&#34; | safeHTML }}<span style="color:#5bc4bf">&lt;/lastBuildDate&gt;</span>{{ end }}
</span></span><span style="display:flex;"><span>    {{ with .OutputFormats.Get &#34;RSS&#34; }}{{ printf `<span style="color:#5bc4bf">&lt;atom:link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">%q</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;self&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">%q</span> <span style="color:#5bc4bf">/&gt;</span>` .Permalink .MediaType | safeHTML }}{{ end }}
</span></span><span style="display:flex;"><span>    {{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
</span></span><span style="display:flex;"><span>    {{- $pages := where site.Pages &#34;.Params.disable_feed&#34; &#34;!=&#34; true -}}
</span></span><span style="display:flex;"><span>    {{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
</span></span><span style="display:flex;"><span>    {{- range first $limit $pages }}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;item&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;title&gt;</span>{{ .Title }}<span style="color:#5bc4bf">&lt;/title&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;link&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/link&gt;</span>
</span></span><span style="display:flex;"><span>        {{ with .Summary }}<span style="color:#5bc4bf">&lt;description&gt;</span>{{ . | html }}<span style="color:#5bc4bf">&lt;/description&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>        {{ with site.Params.author.email }}<span style="color:#5bc4bf">&lt;author&gt;</span>{{.}}{{ with site.Params.author.name }} ({{.}}){{end}}<span style="color:#5bc4bf">&lt;/author&gt;</span>{{end}}{{ $url := printf &#34;%s&#34; &#34;/tags/&#34; | absLangURL }}
</span></span><span style="display:flex;"><span>        {{ with .Params.tags }}{{ range . }}<span style="color:#5bc4bf">&lt;category</span> <span style="color:#06b6ef">domain=</span><span style="color:#48b685">&#34;{{ $url }}{{urlize .}}/&#34;</span><span style="color:#5bc4bf">&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/category&gt;</span>{{end}}{{end}}
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;guid&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/guid&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;pubDate&gt;</span>{{ .Date.Format &#34;Mon, 02 Jan 2006 15:04:05 -0700&#34; | safeHTML }}<span style="color:#5bc4bf">&lt;/pubDate&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;/item&gt;</span>
</span></span><span style="display:flex;"><span>    {{ end }}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;/channel&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;/rss&gt;</span>
</span></span></code></pre></div><h3 id="atom">Atom</h3>
<p>Nativement Hugo ne génére pas de flux Atom. Il faut tout créer ; ce n&rsquo;est pas
bien difficile !</p>
<p>Il est nécessaire de modifier le fichier de configuration pour :</p>
<ul>
<li>créer un nouveau <a href="/fr/web/hugo/hugo-feed/#atommediatype">type de média</a></li>
<li>créer un nouveau <a href="/fr/web/hugo/hugo-feed/#atomouputformat">format de sortie</a></li>
<li>créer le <a href="/fr/web/hugo/hugo-feed/#atomtemplate">modèle</a> pour le flux Atom</li>
</ul>
<h4 id="atommediatype">Atom::MediaType</h4>
<h5 id="hugo--020">Hugo &gt;= 0.20</h5>
<p>Depuis Hugo 0.20, il faut ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;application/atom+xml&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffix</span> = <span style="color:#48b685">&#34;xml&#34;</span>
</span></span></code></pre></div><p>Là, nous avons donc implémenté un nouveau type de format ayant pour mime
type : <code>application/atom+xml</code>, et pour nom d&rsquo;extension : <code>xml</code>.</p>
<h5 id="hugo--044">Hugo &gt;= 0.44</h5>
<p>Depuis Hugo 0.44, pour que cela fonctionne correctement il faut ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">mediaTypes</span>]
</span></span><span style="display:flex;"><span>    [<span style="color:#06b6ef">mediaTypes</span>.<span style="color:#48b685">&#34;application/atom+xml&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffixes</span> = [<span style="color:#48b685">&#34;xml&#34;</span>]
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si votre ancienne configuration précédait la 0.44, il faut adapter/transformer
la variable <code>suffix</code> en <code>suffixes = ['xml']</code> !</div>

<h4 id="atomouputformat">Atom::OuputFormat</h4>
<p>La déclaration du format de sortie, à ajouter  :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">Atom</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span> = <span style="color:#48b685">&#34;atom&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">isPlainText</span> = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span> = <span style="color:#48b685">&#34;application/atom+xml&#34;</span>
</span></span></code></pre></div><p>Puis, il faut ajouter <code>&quot;ATOM&quot;</code> à votre variable <code>home</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;ATOM&#34;</span>, <span style="color:#48b685">&#34;RSS&#34;</span>]
</span></span></code></pre></div><h4 id="atomtemplate">Atom::Template</h4>
<p>Le modèle peut simplement être créé dans le répertoire <code>layouts/</code> et se
nommer <code>index.atom.xml</code>, ou être dans son sous-répertoire <code>_default/</code> et
se nommer, par exemple : <code>home.atom.xml</code>.</p>
<ul>
<li>Si le site est multilangue, les liens alternatifs vers la version de
langue correspondante à l&rsquo;entrée du site, aux flux atom, 

















































































<abbr lang="en" title="Really Simple Syndication">RSS</abbr>






























,
voire 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 sont générés.</li>
</ul>
<hr>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>{{ printf `<span style="color:#776e71">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; standalone=&#34;yes&#34; ?&gt;</span>` | safeHTML }}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;feed</span> <span style="color:#06b6ef">xmlns=</span><span style="color:#48b685">&#34;http://www.w3.org/2005/Atom&#34;</span> <span style="color:#06b6ef">xml:lang=</span><span style="color:#48b685">&#34;{{ with site.Language.Lang }}{{.}}{{end}}&#34;</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;id&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;title&gt;</span>{{ if eq .Title  site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{.}}{{ T &#34;on&#34; }}{{ end }}&#39;{{ site.Title }}&#39;{{ end }}<span style="color:#5bc4bf">&lt;/title&gt;</span>
</span></span><span style="display:flex;"><span>    {{ with site.Params.description -}}<span style="color:#5bc4bf">&lt;subtitle&gt;</span>{{ . }}<span style="color:#5bc4bf">&lt;/subtitle&gt;</span>{{- end }}
</span></span><span style="display:flex;"><span>    {{ with .OutputFormats.Get &#34;ATOM&#34; }}{{ printf `<span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">%q</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;self&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">%q</span> <span style="color:#5bc4bf">/&gt;</span>` .Permalink .MediaType | safeHTML }}{{end}}
</span></span><span style="display:flex;"><span>    {{ range .AlternativeOutputFormats -}}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">&#34;{{ if eq .Name &#34;</span><span style="color:#ef6155">HTML&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">$.Permalink</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">else</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">printf</span> <span style="color:#ef6155">`%s%s.%s`</span> <span style="color:#ef6155">$.Permalink</span> <span style="color:#ef6155">(.Name</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">lower)</span> <span style="color:#ef6155">(index</span> <span style="color:#ef6155">.MediaType.Suffixes</span> <span style="color:#ef6155">0)</span> <span style="color:#ef6155">}}{{end}}&#34;</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;alternate&#34;</span> <span style="color:#ef6155">{{</span> <span style="color:#ef6155">printf</span> <span style="color:#ef6155">&#34;</span><span style="color:#06b6ef">type=</span><span style="color:#48b685">%q&#34;</span> <span style="color:#ef6155">.MediaType.Type</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">safeHTMLAttr</span> <span style="color:#ef6155">}}</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    {{end}}{{ if hugo.IsMultilingual }}{{ range site.Languages }}{{ if ne .Lang site.Language.Lang }}{{ $lang := .Lang }}
</span></span><span style="display:flex;"><span>    {{ with $.OutputFormats.Get &#34;ATOM&#34; }}{{ printf `<span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">%q</span> <span style="color:#06b6ef">hreflang=</span><span style="color:#48b685">%q</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;alternate&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">%q</span> <span style="color:#5bc4bf">/&gt;</span>` (print $lang &#34;/&#34; .Name &#34;.&#34; (index .MediaType.Suffixes 0) |absURL) $lang .MediaType | safeHTML }}{{end}}
</span></span><span style="display:flex;"><span>    {{ range $.AlternativeOutputFormats -}}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">&#34;{{ if eq .Name &#34;</span><span style="color:#ef6155">HTML&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">printf</span> <span style="color:#ef6155">`%s/`</span> <span style="color:#ef6155">$lang</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">absURL</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">else</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">printf</span> <span style="color:#ef6155">`%s/%s.%s`</span> <span style="color:#ef6155">$lang</span> <span style="color:#ef6155">(.Name</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">lower)</span> <span style="color:#ef6155">(index</span> <span style="color:#ef6155">.MediaType.Suffixes</span> <span style="color:#ef6155">0)</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">absURL</span> <span style="color:#ef6155">}}{{end}}&#34;</span> <span style="color:#06b6ef">hreflang=</span><span style="color:#48b685">&#34;{{ $lang }}&#34;</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;alternate&#34;</span> <span style="color:#ef6155">{{</span> <span style="color:#ef6155">printf</span> <span style="color:#ef6155">&#34;</span><span style="color:#06b6ef">type=</span><span style="color:#48b685">%q&#34;</span> <span style="color:#ef6155">.MediaType.Type</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">safeHTMLAttr</span> <span style="color:#ef6155">}}</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    {{end}}{{end}}{{end}}{{end}}{{ with site.Copyright }}{{ $lang := site.Language.Lang }}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">&#34;http://creativecommons.org/publicdomain/zero/1.0/legalcode.{{ $lang }}&#34;</span> <span style="color:#06b6ef">hreflang=</span><span style="color:#48b685">&#34;{{ $lang }}&#34;</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;license&#34;</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">&#34;http://creativecommons.org/publicdomain/zero/1.0/deed.{{ $lang }}&#34;</span> <span style="color:#06b6ef">hreflang=</span><span style="color:#48b685">&#34;{{ $lang }}&#34;</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;license&#34;</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;rights&gt;</span>© {{ $.Date.Format &#34;2006&#34; | safeHTML }} {{ site.Params.author.name }}<span style="color:#5bc4bf">&lt;/rights&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;icon&gt;</span>/img/favicon.ico<span style="color:#5bc4bf">&lt;/icon&gt;</span>
</span></span><span style="display:flex;"><span>    {{ with site.Params.logo }}<span style="color:#5bc4bf">&lt;logo&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/logo&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    {{ if not .Date.IsZero }}<span style="color:#5bc4bf">&lt;updated&gt;</span>{{ .Date.Format &#34;2006-01-02T15:04:05-07:00&#34; | safeHTML }}<span style="color:#5bc4bf">&lt;/updated&gt;</span>{{ end }}
</span></span><span style="display:flex;"><span>    {{ with site.Params.author.name }}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;author&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;name&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/name&gt;</span>
</span></span><span style="display:flex;"><span>        {{ with site.Params.author.email }}<span style="color:#5bc4bf">&lt;email&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/email&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;uri&gt;</span>{{ $.Permalink }}<span style="color:#5bc4bf">&lt;/uri&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;/author&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;generator</span> <span style="color:#06b6ef">uri=</span><span style="color:#48b685">&#34;https://gohugo.io&#34;</span> <span style="color:#06b6ef">version=</span><span style="color:#48b685">&#34;{{ Hugo.Version }}&#34;</span><span style="color:#5bc4bf">&gt;</span>Hugo<span style="color:#5bc4bf">&lt;/generator&gt;</span>
</span></span><span style="display:flex;"><span>    {{- $limit := (cond (le site.Config.Services.RSS.Limit 0) 65536 site.Config.Services.RSS.Limit) -}}
</span></span><span style="display:flex;"><span>    {{- $pages := where site.RegularPages &#34;.Params.disable_feed&#34; &#34;!=&#34; true -}}
</span></span><span style="display:flex;"><span>    {{- if ge $limit 1 -}}{{- $pages = $pages | first $limit -}}{{- end -}}
</span></span><span style="display:flex;"><span>    {{- range first $limit $pages }}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;entry&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;id&gt;</span>{{ .Permalink }}<span style="color:#5bc4bf">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;link</span> <span style="color:#06b6ef">href=</span><span style="color:#48b685">&#34;{{ .Permalink }}&#34;</span> <span style="color:#06b6ef">rel=</span><span style="color:#48b685">&#34;alternate&#34;</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;text/html&#34;</span> <span style="color:#5bc4bf">/&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;title&gt;</span>{{ .Title }}<span style="color:#5bc4bf">&lt;/title&gt;</span>{{ with site.Params.author }}
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;author&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#5bc4bf">&lt;name&gt;</span>{{.}}<span style="color:#5bc4bf">&lt;/name&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;/author&gt;</span>{{end}}{{ $url := printf &#34;%s&#34; &#34;/tags/&#34; | absLangURL }}{{ with .Params.tags }}{{ range . }}
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;category</span> <span style="color:#06b6ef">term=</span><span style="color:#48b685">&#34;{{.}}&#34;</span> <span style="color:#06b6ef">scheme=</span><span style="color:#48b685">&#34;{{ print $url (urlize .) | absLangURL }}/&#34;</span> <span style="color:#5bc4bf">/&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>        {{end}}
</span></span><span style="display:flex;"><span>        {{ with .Content }}<span style="color:#5bc4bf">&lt;content</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;html&#34;</span><span style="color:#5bc4bf">&gt;</span>{{ `<span style="color:#776e71">&lt;![CDATA[` | safeHTML }}{{.}}]]&gt;</span><span style="color:#5bc4bf">&lt;/content&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>        {{ with .Summary }}<span style="color:#5bc4bf">&lt;summary</span> <span style="color:#06b6ef">type=</span><span style="color:#48b685">&#34;html&#34;</span><span style="color:#5bc4bf">&gt;</span>{{ `<span style="color:#776e71">&lt;![CDATA[` | safeHTML }}{{.}}]]&gt;</span><span style="color:#5bc4bf">&lt;/summary&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&lt;published&gt;</span>{{ .Date.Format &#34;2006-01-02T15:04:05-07:00&#34; | safeHTML }}<span style="color:#5bc4bf">&lt;/published&gt;</span>
</span></span><span style="display:flex;"><span>        {{ if gt .Lastmod .Date }}<span style="color:#5bc4bf">&lt;updated&gt;</span>{{ .Lastmod.Format &#34;2006-01-02T15:04:05-07:00&#34; | safeHTML }}<span style="color:#5bc4bf">&lt;/updated&gt;</span>{{end}}
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&lt;/entry&gt;</span>
</span></span><span style="display:flex;"><span>    {{ end }}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;/feed&gt;</span>
</span></span></code></pre></div><h3 id="json">JSON</h3>
<p>Pour générer le flux 














































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 , nous nous conformerons à la norme















































<abbr lang="en" title="JavaScript Object Notation">JSON</abbr>

































































 Feed v1.</p>
<h4 id="jsonoutputformat">JSON::OutputFormat</h4>
<p>La déclaration de sortie de format à ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputFormats</span>.<span style="color:#06b6ef">JSON</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mediaType</span>             = <span style="color:#48b685">&#34;application/json&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">baseName</span>              = <span style="color:#48b685">&#34;feed&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">suffix</span>                = <span style="color:#48b685">&#34;json&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">IsHTML</span>                = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">IsPlainText</span>           = <span style="color:#815ba4">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">noUgly</span>                = <span style="color:#815ba4">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">rel</span>                   = <span style="color:#48b685">&#34;alternate&#34;</span>
</span></span></code></pre></div><p>Puis, il faut ajouter la déclaration <code>JSON</code> à votre variable <code>home</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#06b6ef">outputs</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">`</span><span style="color:#06b6ef">home</span> = [<span style="color:#48b685">&#34;HTML&#34;</span>, <span style="color:#48b685">&#34;ATOM&#34;</span>, <span style="color:#48b685">&#34;JSON&#34;</span>, <span style="color:#48b685">&#34;RSS&#34;</span>]
</span></span></code></pre></div><h4 id="jsontemplate">JSON::Template</h4>
<h5 id="json-détails">JSON: Détails</h5>
<p>En plus de la <a href="/fr/web/hugo/hugo-feed/#limite">limite</a> mentionnée plus haut, nous récupèrons le nombre
de page, pour boucler correctement car le dernier <code>item</code> ne doit pas être suivi
du symbole &lsquo;,&rsquo; :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{- $length := (len $pages) -}}
</code></pre><p>Et en fin de boucle <code>range</code>, nous ajoutons :</p>
<pre tabindex="0"><code class="language-hugo" data-lang="hugo">{{ if ne (add $index 1) $length }},{{ end }}
</code></pre><p>Ainsi tant qu&rsquo;il y a un élément suivant, il est précédé du symbole &lsquo;,&rsquo;
jusqu&rsquo;au dernier.</p>
<hr>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">$limit</span> <span style="color:#ef6155">:=</span> <span style="color:#ef6155">(cond</span> <span style="color:#ef6155">(le</span> <span style="color:#ef6155">site.Config.Services.RSS.Limit</span> <span style="color:#ef6155">0)</span> <span style="color:#ef6155">65536</span> <span style="color:#ef6155">site.Config.Services.RSS.Limit)</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">$pages</span> <span style="color:#ef6155">:=</span> <span style="color:#ef6155">where</span> <span style="color:#ef6155">site.RegularPages</span> <span style="color:#5bc4bf">&#34;.Params.disable_feed&#34;</span> <span style="color:#48b685">&#34;!=&#34;</span> <span style="color:#815ba4">true</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">if</span> <span style="color:#ef6155">ge</span> <span style="color:#ef6155">$limit</span> <span style="color:#ef6155">1</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">$pages</span> <span style="color:#ef6155">=</span> <span style="color:#ef6155">$pages</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">first</span> <span style="color:#ef6155">$limit</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">$length</span> <span style="color:#ef6155">:=</span> <span style="color:#ef6155">(len</span> <span style="color:#ef6155">$pages)</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&#34;version&#34;</span>: <span style="color:#48b685">&#34;https://jsonfeed.org/version/1&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&#34;title&#34;</span>: <span style="color:#48b685">&#34;{{ site.Title }}&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">&#34;home_page_url&#34;</span>: <span style="color:#48b685">&#34;{{ site.BaseURL }}&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">{{</span> <span style="color:#ef6155">with</span>  <span style="color:#ef6155">.OutputFormats.Get</span> <span style="color:#5bc4bf">&#34;JSON&#34;</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span><span style="color:#48b685">&#34;feed_url&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;{{.Permalink}}&#34;</span><span style="color:#ef6155">,</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">site.Params.description</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span><span style="color:#48b685">&#34;description&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;{{ . }}&#34;</span><span style="color:#ef6155">,</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">site.Params.author.name</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;author&#34;</span><span style="color:#ef6155">:</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&#34;avatar&#34;</span>: <span style="color:#48b685">&#34;{{ with site.Params.logo }}{{ . }}{{ end}}&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&#34;name&#34;</span>: <span style="color:#48b685">&#34;{{ . }}&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">&#34;url&#34;</span>: <span style="color:#48b685">&#34;http://huc.fr.eu.org&#34;</span>
</span></span><span style="display:flex;"><span>        }<span style="color:#ef6155">,</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">site.Params.logo</span> }<span style="color:#ef6155">}</span><span style="color:#48b685">&#34;icon&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;{{ . }}&#34;</span><span style="color:#ef6155">,</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;favicon&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;/img/favicon.ico&#34;</span><span style="color:#ef6155">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;items&#34;</span><span style="color:#ef6155">:</span> [ {<span style="color:#ef6155">{-</span> <span style="color:#ef6155">range</span> <span style="color:#ef6155">$index,</span> <span style="color:#ef6155">$elements</span> <span style="color:#ef6155">:=</span> <span style="color:#ef6155">$pages</span> <span style="color:#ef6155">-</span>}<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#5bc4bf">&#34;id&#34;</span>: <span style="color:#48b685">&#34;{{ .Permalink }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#5bc4bf">&#34;url&#34;</span>: <span style="color:#48b685">&#34;{{ .Permalink }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#5bc4bf">&#34;title&#34;</span>: <span style="color:#48b685">&#34;{{ .Title | plainify }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#ef6155">{{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">site.Params.Author</span> }<span style="color:#ef6155">}</span><span style="color:#48b685">&#34;author&#34;</span><span style="color:#ef6155">:</span> { <span style="color:#5bc4bf">&#34;name&#34;</span>: <span style="color:#48b685">&#34;{{ . }}&#34;</span> }{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">.Content</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;content_text&#34;</span><span style="color:#ef6155">:</span> {<span style="color:#ef6155">{</span> <span style="color:#ef6155">.</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">plainify</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">jsonify</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;content_html&#34;</span><span style="color:#ef6155">:</span> {<span style="color:#ef6155">{</span> <span style="color:#ef6155">.</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">safeHTML</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">jsonify</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">.Summary</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;summary&#34;</span><span style="color:#ef6155">:</span> {<span style="color:#ef6155">{</span> <span style="color:#ef6155">.</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">plainify</span> <span style="color:#ef6155">|</span> <span style="color:#ef6155">jsonify</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">with</span> <span style="color:#ef6155">.Params.tags</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;tags&#34;</span><span style="color:#ef6155">:</span> [{<span style="color:#ef6155">{</span> <span style="color:#ef6155">range</span> <span style="color:#ef6155">$tindex,</span> <span style="color:#ef6155">$tag</span> <span style="color:#ef6155">:=</span> <span style="color:#ef6155">.</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">if</span> <span style="color:#ef6155">$tindex</span> }<span style="color:#ef6155">}</span>, {<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span><span style="color:#48b685">&#34;{{ $tag| htmlEscape }}&#34;</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>]{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">if</span> <span style="color:#ef6155">.PublishDate</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;date_published&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;{{ .PublishDate.Format &#34;</span><span style="color:#f99b15">2006-01-02</span><span style="color:#ef6155">T</span><span style="color:#f99b15">15</span><span style="color:#ef6155">:</span><span style="color:#f99b15">04</span><span style="color:#ef6155">:</span><span style="color:#f99b15">05-01</span><span style="color:#ef6155">:</span><span style="color:#f99b15">00</span><span style="color:#48b685">&#34; | safeHTML }}&#34;</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">if</span> <span style="color:#ef6155">gt</span> <span style="color:#ef6155">.Lastmod</span> <span style="color:#ef6155">.Date</span> }<span style="color:#ef6155">}</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#34;date_modified&#34;</span><span style="color:#ef6155">:</span> <span style="color:#48b685">&#34;{{ .Lastmod.Format &#34;</span><span style="color:#f99b15">2006-01-02</span><span style="color:#ef6155">T</span><span style="color:#f99b15">15</span><span style="color:#ef6155">:</span><span style="color:#f99b15">04</span><span style="color:#ef6155">:</span><span style="color:#f99b15">05-01</span><span style="color:#ef6155">:</span><span style="color:#f99b15">00</span><span style="color:#48b685">&#34; | safeHTML }}&#34;</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">}</span>{<span style="color:#ef6155">{</span> <span style="color:#ef6155">if</span> <span style="color:#ef6155">ne</span> <span style="color:#ef6155">(add</span> <span style="color:#ef6155">$index</span> <span style="color:#ef6155">1)</span> <span style="color:#ef6155">$length</span> }<span style="color:#ef6155">}</span>,{<span style="color:#ef6155">{</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>{<span style="color:#ef6155">{-</span> <span style="color:#ef6155">end</span> }<span style="color:#ef6155">}</span>
</span></span><span style="display:flex;"><span>    ]
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><h2 id="documentations-tierces">Documentations tierces</h2>
<ul>
<li>RFC 3339 : <a href="https://tools.ietf.org/html/rfc3339" rel="external">https://tools.ietf.org/html/rfc3339</a></li>
<li>RFC 4122 : <a href="https://tools.ietf.org/html/rfc4122" rel="external">https://tools.ietf.org/html/rfc4122</a></li>
<li>RFC 4151 : <a href="https://tools.ietf.org/html/rfc4151" rel="external">https://tools.ietf.org/html/rfc4151</a></li>
<li>RFC 4287 : <a href="https://tools.ietf.org/html/rfc4287" rel="external">https://tools.ietf.org/html/rfc4287</a></li>
<li>RFC 5988 : <a href="https://tools.ietf.org/html/rfc5988" rel="external">https://tools.ietf.org/html/rfc5988</a></li>
<li>RFC 8288 : <a href="https://tools.ietf.org/html/rfc8288" rel="external">https://tools.ietf.org/html/rfc8288</a></li>
<li>Norme ISO 8601 : <a href="https://www.w3.org/TR/1998/NOTE-datetime-19980827" rel="external">https://www.w3.org/TR/1998/NOTE-datetime-19980827</a></li>
<li>L&rsquo;article d&rsquo;OpenWeb : <a href="https://openweb.eu.org/articles/comment-construire-un-flux-atom" rel="external">Comment construire un flux Atom ?</a></li>
<li>Plus d&rsquo;informations sur la norme d&rsquo;identification <code>tag</code> sur le site <a href="http://www.taguri.org/" rel="external">Tag URI</a></li>
<li>Plus d&rsquo;informations sur les UUID : <a href="https://fr.wikipedia.org/wiki/Universal_Unique_Identifier" title="Article Wikipédia : Universal_Unique_Identifier">Universal_Unique_Identifier <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li>La spécification JSON Feed 1 : <a href="https://jsonfeed.org/version/1" rel="external">https://jsonfeed.org/version/1</a></li>
<li>La spécification RSS 2.0 : <a href="https://cyber.harvard.edu/rss/index.html" rel="external">https://cyber.harvard.edu/rss/index.html</a></li>
<li>Le sujet <a href="https://discourse.gohugo.io/t/atom-and-json-feeds/13572" rel="external">Atom and JSON feeds</a> sur le forum de la communauté Hugo - <em>qui m&rsquo;a bien aidé</em>.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place un flux de données RSS, ET Atom, voire JSON !]]></summary>
        <published>2019-12-11T18:35:25+01:00</published>
        <updated>2019-12-12T20:17:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9baf8cd1-80e9-193d-a8aa-eab3e22793b0</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-search-jqueryui-autocomplete/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo Search : un moteur de recherche interne (JQueryUI Autocomplete)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="search" scheme="http://doc.huc.fr.eu.org/fr/tags/search/" />
        <category term="JQuery" scheme="http://doc.huc.fr.eu.org/fr/tags/jquery/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Intégrer une fonction de recherche au sein du site généré par Hugo peut
se faire de différentes manières.</p>
<p>On va implémenter une manière très simple avec JQuery+UI, et cela nous
prendra vraiment très peu de temps.</p>
<p>Étant donné  qu&rsquo;on peut parcourir l&rsquo;ensemble des pages du site grâce à
la variable globale <code>site.Pages</code>, on va se servir du mécanisme de la
méthode <code>autocomplete()</code> fournie par la bibliothèque JQueryUI, pour
restituer les différents résultats selon le texte écrit.</p>
<p>Bien sûr, j&rsquo;assume le fait que vous savez intégrer les appels de scripts
JQuery et JQueryUI au sein de votre propre site.</p>
<h2 id="codes">Codes</h2>
<h3 id="jqueryui">JQueryUI</h3>
<p>Pour la partie JQuery, nous utilisons la gestion des événements de la
méthode <code>autocomplete()</code>, à la différence près est que la variable
<code>projects</code> va être implémentée par le biais de la fonction Hugo <code>range</code>.</p>
<p>Le code JQuery :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span><span style="color:#06b6ef">script</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$</span>(<span style="color:#815ba4">function</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">var</span> <span style="color:#06b6ef">projects</span> <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">range</span> <span style="color:#06b6ef">site</span>.<span style="color:#06b6ef">Pages</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>            {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">$url</span> <span style="color:#5bc4bf">:=</span> .<span style="color:#06b6ef">RelPermalink</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>            {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">$title</span> <span style="color:#5bc4bf">:=</span> .<span style="color:#06b6ef">LinkTitle</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">value</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ $title }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">label</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url &#34;</span><span style="color:#06b6ef">tags</span><span style="color:#48b685">&#34; }}{{- T &#34;</span><span style="color:#06b6ef">pageListTitle</span><span style="color:#48b685">&#34; }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">url</span><span style="color:#5bc4bf">:</span><span style="color:#48b685">&#34;{{ $url }}&#34;</span>
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">end</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">autocomplete</span>({
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">minLength</span><span style="color:#5bc4bf">:</span> <span style="color:#f99b15">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">source</span><span style="color:#5bc4bf">:</span> <span style="color:#06b6ef">projects</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">focus</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">select</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#replyer&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#06b6ef">data</span>(<span style="color:#48b685">&#39;ui-autocomplete&#39;</span>).<span style="color:#06b6ef">_renderItem</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">function</span>(<span style="color:#06b6ef">ul</span>, <span style="color:#06b6ef">item</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#39;&lt;li&gt;&#39;</span>)
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">append</span>(<span style="color:#48b685">&#39;&lt;a href=&#34;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">url</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34; alt=&#34;&#39;</span><span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34;&gt;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&lt;/a&gt;&#39;</span> )
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">appendTo</span>(<span style="color:#06b6ef">ul</span>);
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span><span style="color:#ef6155">/script&gt;</span>
</span></span></code></pre></div><h3 id="html">HTML</h3>
<p>Quant à la partie HTML, elle est très simple ; il faut à minima les deux
éléments <code>input</code> suivants :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;form-control&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">placeholder</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ T &#34;</span><span style="color:#06b6ef">searchHolderTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">aria-hidden</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;true&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;replyer&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;hidden&#34;</span>&gt;
</span></span></code></pre></div><ul>
<li>Le premier élément <code>input</code> est celui qui &ldquo;capte&rdquo; le texte recherché</li>
<li>le second va permettre de retourner les informations trouvées.</li>
<li>La déclaration Hugo <code>{{ i18n &quot;searchHolderTitle&quot; }}</code> est juste pour le
contexte multilangue de ce site ; à remplacer par du texte selon votre goût…</li>
</ul>
<p>Que vous faites suivre du code Hugo puis du code JQuery</p>
<h3 id="tldr">TL;DR</h3>
<p>L&rsquo;ensemble du code :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;form-control&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;search&#34;</span> <span style="color:#06b6ef">placeholder</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ T &#34;</span><span style="color:#06b6ef">searchHolderTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">input</span> <span style="color:#06b6ef">aria-hidden</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;true&#34;</span> <span style="color:#06b6ef">id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;replyer&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;hidden&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    {{- $baseURL := site.BaseURL | absLangURL -}}
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">&lt;!-- Javascript --&gt;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">script</span>&gt;
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">$</span>(<span style="color:#815ba4">function</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">var</span> <span style="color:#06b6ef">projects</span> <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">range</span> <span style="color:#06b6ef">site</span>.<span style="color:#06b6ef">Pages</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>            {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">$url</span> <span style="color:#5bc4bf">:=</span> .<span style="color:#06b6ef">RelPermalink</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>            {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">$title</span> <span style="color:#5bc4bf">:=</span> .<span style="color:#06b6ef">LinkTitle</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">value</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{ $title }}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">label</span><span style="color:#5bc4bf">:</span> <span style="color:#48b685">&#34;{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url &#34;</span><span style="color:#06b6ef">tags</span><span style="color:#48b685">&#34; }}{{- T &#34;</span><span style="color:#06b6ef">pageListTitle</span><span style="color:#48b685">&#34; }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">url</span><span style="color:#5bc4bf">:</span><span style="color:#48b685">&#34;{{ $url }}&#34;</span>
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {{<span style="color:#5bc4bf">-</span> <span style="color:#06b6ef">end</span> <span style="color:#5bc4bf">-</span>}}
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">autocomplete</span>({
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">minLength</span><span style="color:#5bc4bf">:</span> <span style="color:#f99b15">0</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">source</span><span style="color:#5bc4bf">:</span> <span style="color:#06b6ef">projects</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">focus</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">select</span><span style="color:#5bc4bf">:</span> <span style="color:#815ba4">function</span>( <span style="color:#06b6ef">event</span>, <span style="color:#06b6ef">ui</span> ) {
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#search&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#34;#replyer&#34;</span>).<span style="color:#06b6ef">val</span>( <span style="color:#06b6ef">ui</span>.<span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> );
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> <span style="color:#815ba4">false</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#06b6ef">data</span>(<span style="color:#48b685">&#39;ui-autocomplete&#39;</span>).<span style="color:#06b6ef">_renderItem</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">function</span>(<span style="color:#06b6ef">ul</span>, <span style="color:#06b6ef">item</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#06b6ef">$</span>(<span style="color:#48b685">&#39;&lt;li&gt;&#39;</span>)
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">append</span>(<span style="color:#48b685">&#39;&lt;a href=&#34;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">url</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34; alt=&#34;&#39;</span><span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">label</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&#34;&gt;&#39;</span> <span style="color:#5bc4bf">+</span> <span style="color:#06b6ef">item</span>.<span style="color:#06b6ef">value</span> <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;&lt;/a&gt;&#39;</span> )
</span></span><span style="display:flex;"><span>        .<span style="color:#06b6ef">appendTo</span>(<span style="color:#06b6ef">ul</span>);
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>});
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">script</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><p>Et, voilà ! <br>
En quelques minutes, un &ldquo;moteur de recherche&rdquo; interne intégré à votre site Hugo.</p>
<hr>
<h2 id="démonstration">Démonstration</h2>
<p>Pour ce qui est de la démonstration, c&rsquo;est ce qu&rsquo;il y a dans le menu,
en haut à droite de chacune des pages du site.</p>
<hr>
<h2 id="documentations">Documentations</h2>
<ul>
<li>La documentation officielle : <a href="https://gohugo.io/tools/search/" title="Lien vers la page du site officiel Hugo : Tools &gt; Search">Hugo Documentation : Tools &gt; Search</a>
 - <em>lien en anglais</em></li>
<li>La fonction Hugo <code>range</code> : <a href="https://gohugo.io/functions/range/" title="Lien vers la page du site officiel Hugo : Functions &gt; Range">Hugo Documentation : Functions &gt; Range</a>
 - <em>lien en anglais</em></li>
<li>Inspiré par le <a href="https://themes.gohugo.io/theme/dot-hugo-documentation-theme/" rel="external">thème Dot</a> - <em>(cf : <a href="https://github.com/themefisher/dot/blob/master/layouts/partials/banner.html" rel="external">banner.html</a>)</em></li>
<li>La méthode JQuery UI <code>autocomplete()</code> : <a href="https://jqueryui.com/autocomplete" rel="external">https://jqueryui.com/autocomplete</a> - <em>lien en anglais</em></li>
<li>De plus amples explications sur la méthode <code>Autocomplete()</code> de JQueryUI : lire la <a href="https://www.tutorialspoint.com/jqueryui/jqueryui_autocomplete.htm" rel="external">documentation</a>  - <em>lien en anglais</em></li>
<li>Une autre méthode de <a href="https://fr.jeffprod.com/blog/2018/un-moteur-de-recherche-interne-pour-votre-site-hugo/" rel="external">moteur de recherche interne</a>, cette fois-ci avec les bibliothèques VueJS + Axios</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment intégrer un moteur de recherche dans Hugo, avec JQuery UI autocomplete()]]></summary>
        <published>2019-12-06T01:21:00+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e6f2de57-7366-c750-2fe6-8415b07f5a9c</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-shortcodes/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo Shortcodes</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="Shortcode" scheme="http://doc.huc.fr.eu.org/fr/tags/shortcode/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un shortcode Hugo est un fichier contenant un type précis d&rsquo;éléments





























<span lang="en">HTML <em>(HyperText Markup Language)</em></span>


















































































 pour pouvoir augmenter les possibilités d&rsquo;Hugo.</p>
<p>Lors d&rsquo;un appel de ce shortcode depuis un fichier 





















































<span lang="en">MD <em>(MarkDown)</em></span>

























































,
un traitement est fait afin de remplacer l&rsquo;appel du shorcode par le
traitement restitué par le shortcode lui-même.</p>
<p>Il est ainsi possible par ce biais d&rsquo;appeler des iframes, des figures,
etc… voire un fichier 






















































<abbr lang="en" title="MarkDown">MD</abbr>

























































 lui-même.</p>
<p>Les shortcodes s&rsquo;enregistrent dans le répertoire <code>layout/shortcodes/</code>.</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>l&rsquo;officielle, en anglais : <a href="https://gohugo.io/content-management/shortcodes/" title="Lien vers la page du site officiel Hugo : Content management &gt; Shortcodes">Hugo Documentation : Content management &gt; Shortcodes</a>
</li>
</ul>
<h2 id="mes-shortcodes">Mes shortcodes</h2>
<p>Mes usages pour l&rsquo;instant sont très basiques ; en soit ce que je fais
au-travers de plusieurs pourraient être directement écrit dans le fichier























































<abbr lang="en" title="MarkDown">MD</abbr>

























































 au format 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, et zou, basta…</p>
<p>Néanmoins, il faut avouer que pour l&rsquo;inclusion d&rsquo;exemples de code,
surtout dans un site multilangue est franchement utile.</p>
<h3 id="abbreviations">abbreviations</h3>
<p>Ce shortcode a deux versions légérement différentes. <br>
J&rsquo;ai commencé historiquement avec la version <a href="/fr/web/hugo/hugo-shortcodes/#abbr-v1">v1</a> puis au cours d&rsquo;une
refonte en novembre 2025, j&rsquo;ai écrit une <a href="/fr/web/hugo/hugo-shortcodes/#abbr-v2">v2</a> qui a pour avantage lors
du premier appel concernant un sigle/une abbréviation d&rsquo;écrire la définition à
côté de celui-ci, puis pour les appels suivants s&rsquo;ils existent dans la page
en cours, de les afficher sous forme d&rsquo;abbréviations 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































.</p>
<h4 id="abbr-v1">abbr-v1</h4>
<p>Gestion des abbréviations, élément 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 <code>abbr</code> :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/abbr.html" title="">abbr</a></p>
</div>

Le shortcode :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">abbr</span> <span style="color:#ef6155">{{</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Get</span> <span style="color:#06b6ef">1</span> <span style="color:#ef6155">|</span> <span style="color:#06b6ef">printf</span> <span style="color:#ef6155">`</span><span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">%q`</span> <span style="color:#ef6155">|</span> <span style="color:#06b6ef">safeHTMLAttr</span> <span style="color:#ef6155">}}</span>&gt;{{ .Get 0 | safeHTML }}&lt;/<span style="color:#5bc4bf">abbr</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode est simple :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; abbr accronym &#34;Meaning of Acronym&#34; &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>accronym</code> est l&rsquo;acronyme ou l&rsquo;abbréviation</li>
<li><code>Meaning of Acronym</code> est la signification de l&rsquo;acronyme</li>
</ul>
<hr>
<p>Exemple : <abbr title="HyperText Markup Language">HTML</abbr>
 est écrit ainsi :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; abbr HTML &#34;HyperText Markup Language&#34; &gt;}}
</code></pre></div>
</p>
<h4 id="abbr-v2">abbr-v2</h4>
<p>Tout commence par l&rsquo;ajout du fichier tiers dans le répertoire <code>data</code>, nommé
<code>terms.yaml</code>.</p>
<p>Chaque terme a au minimum deux entrées :</p>
<ul>
<li>la première nommée <code>abbr</code> qui prend le nom du sigle</li>
<li>la seconde nommée <code>term</code> qui est la définition du sigle</li>
</ul>
<p>Ainsi par exemple, le fichier <code>data/terms.yaml</code> comprendra pour la définition
du terme CSS, l&rsquo;entrée suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>- <span style="color:#5bc4bf">abbr</span>: <span style="color:#f99b15">CSS</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">term</span>: <span style="color:#f99b15">Cascade Style Sheet</span>
</span></span></code></pre></div><hr>
<p>Ensuite le shortcode appelé est <em>- un poil plus compliqué que la v1 -</em> :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/abbr2.html" title="">abbr2</a></p>
</div>

Le shortcode :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{/* variables based on shortcode argument */}}
</span></span><span style="display:flex;"><span>{{- $entry := ( .Get 0 | safeHTML ) -}}
</span></span><span style="display:flex;"><span>{{- $count_id := print $entry &#34;_count&#34; -}}
</span></span><span style="display:flex;"><span>{{/* range over data file */}}
</span></span><span style="display:flex;"><span>{{- range site.Data.terms }}
</span></span><span style="display:flex;"><span>{{/* Find matches */}}
</span></span><span style="display:flex;"><span>    {{- if eq ( .abbr ) $entry }}
</span></span><span style="display:flex;"><span>        {{- if gt ( $.Page.Scratch.Get ( $count_id )) 0 }}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">abbr</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{- .term -}}&#34;</span>&gt;{{- .abbr -}}&lt;/<span style="color:#5bc4bf">abbr</span>&gt;
</span></span><span style="display:flex;"><span>        {{- else -}}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">span</span>&gt;{{- .abbr }} &lt;<span style="color:#5bc4bf">em</span>&gt;({{ .term -}})&lt;/<span style="color:#5bc4bf">em</span>&gt;&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span><span style="display:flex;"><span>{{- $.Page.Scratch.Set ( $count_id ) 1 -}}
</span></span><span style="display:flex;"><span>        {{- end -}}
</span></span><span style="display:flex;"><span>    {{- end -}}
</span></span><span style="display:flex;"><span>{{- end -}}
</span></span></code></pre></div><hr>
<p>Exemple : 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 est écrit ainsi :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; abbr2 HTML &gt;}}
</code></pre></div>
</p>
<p>C&rsquo;est ce qui se passe sur cette page en cours, pour exemple remarquez dès le
début de page ce qu&rsquo;il en est de l&rsquo;accronyme 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































, puis les
récurrences suivantes.</p>
<h3 id="anchor">anchor</h3>
<p>La gestion des ancres dans une même page est un peu plus délicate :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/anchor.html" title="">anchor</a></p>
</div>
</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $txt := .Get 0 | safeHTML }}{{ $name := .Get 1 | lower | safeHTML }}{{ $anchor := anchorize $name }}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ printf &#34;</span><span style="color:#ef6155">%</span><span style="color:#06b6ef">s</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Page</span><span style="color:#ef6155">.</span><span style="color:#06b6ef">RelPermalink</span> <span style="color:#ef6155">}}#{{</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">anchor</span> <span style="color:#ef6155">}}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">shortcodeAnchorTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">name</span> <span style="color:#ef6155">}}&#34;</span>&gt;{{ $txt }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; anchor &#34;Texte&#34; &#34;Cible&#34; &gt;}}
</code></pre></div>
</p>
<hr>
<p>Exemple : Ce <a href="/fr/web/hugo/hugo-shortcodes/#description" title="Se diriger vers l&#39;ancre : description">lien</a>
 renvoie au chapitre
<strong>Description</strong>, et est écrit ainsi :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; anchor &#34;lien&#34; &#34;description&#34; &gt;}}
</code></pre></div>
</p>
<h3 id="blockquote">blockquote</h3>
<p>Ahhh, la gestion des citations, autrement dit des éléments <code>blockquote</code>
m&rsquo;en a fait baver. :p</p>
<p>En même temps, j&rsquo;ai voulu pour des histoires d&rsquo;esthétiques 










<span lang="en">CSS <em>(Cascade Style Sheet)</em></span>





































































































les &ldquo;améliorer&rdquo;.</p>
<p>Basiquement, il suffit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">blockquote</span>&gt;
</span></span><span style="display:flex;"><span>    {{ $file := .Get 0 | readFile | htmlUnescape | safeHTML }}{{ $file }}
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">blockquote</span>&gt;
</span></span></code></pre></div><p>Mon shortcode est un poil plus évolué, car le site étant multilangue, il
appele le shortcode interne dédiée à la gestion multilange, le reste
n&rsquo;étant que de la mise en forme 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































 :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/blockquote.html" title="">blockquote</a></p>
</div>
</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;info-quote&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">p</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;text-white-50&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    {{ T &#34;quoteTitle&#34; }}{{ if .Get 1 }} &lt;<span style="color:#5bc4bf">em</span>&gt;{{ .Get 1 | safeHTML }}&lt;/<span style="color:#5bc4bf">em</span>&gt;{{ end }}
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#5bc4bf">p</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;quote&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#5bc4bf">blockquote</span>&gt;
</span></span><span style="display:flex;"><span>    {{ $name := .Get 0 }}{{ $file := urlize (print &#34;/content/inc/&#34; $name) | readFile | htmlUnescape | safeHTML }}{{ $file }}
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#5bc4bf">blockquote</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode est :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; blockquote &#34;blockquote-filename&#34; lang &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>blockquote-filename</code> est le nom du fichier à appeler contenant la
citation à montrer.</li>
<li><code>lang</code> est le nom de la langue cible, tel <code>en</code>, <code>fr</code>, etc…
<ul>
<li>Pour ne préciser aucun langage en soit, utilisez <code>&quot;&quot;</code></li>
<li><em>deux fois les double quotes</em> -.</li>
</ul>
</li>
</ul>
<hr>
<p>Exemple :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; blockquote &#34;web-hugo-shortcode-example-blockquote&#34; fr &gt;}}
</code></pre></div>
</p>
<p>Restitue :
<div class="info-quote">
    <p>Citation : <em>fr</em></p>
</div>
<div class="quote">
    <figure>
        <blockquote lang="fr"></blockquote>
    </figure>
</div>
</p>
<h3 id="code">Code</h3>
<p>L&rsquo;inclusion de code !</p>
<p>Pour pouvoir utiliser cette fonction, j&rsquo;ai créé à la racine du répertoire
<code>content/</code> un sous répertoire nommé <code>inc</code> - <em>vous pouvez très bien
l&rsquo;appeler autrement, à vous d&rsquo;adapter lors de l&rsquo;appel du shortcode</em> - ;
puis je créé mes fichiers à inclure dans ce répertoire.</p>
<p>Encore une fois, de manière basique, il suffit de :
<div class="info-code">
    <p>Code :&nbsp;<em>html</em></p>
</div>
<div class="code"><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{{ $file := .Get 0 | readFile }}{{ $lang := .Get 1 }}{{ $opt := &#34;&#34; }}&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;code&#34;</span>&gt;{{ highlight $file $lang $opt }}&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div></div>
</p>
<p>Mon shortcode, un poil plus évolué , du fait d&rsquo;être multilangue :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/code.html" title="">code</a></p>
</div>
</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $name := .Get 0 }}{{ $file := urlize (print &#34;/content/inc/&#34; $name) | readFile }}{{ $lang := .Get 1 }}{{ $opt := &#34;&#34; }}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;info-code&#34;</span>&gt;&lt;<span style="color:#5bc4bf">p</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;text-white-50&#34;</span>&gt;{{ i18n &#34;codeTitle&#34; }}&amp;nbsp;&lt;<span style="color:#5bc4bf">em</span>&gt;{{ $lang }}&lt;/<span style="color:#5bc4bf">em</span>&gt;&lt;/<span style="color:#5bc4bf">p</span>&gt;&lt;/<span style="color:#5bc4bf">div</span>&gt;&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;code&#34;</span>&gt;{{ highlight $file $lang $opt }}&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; code &#34;code-filename&#34; language &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>code-filename</code> est le nom du fichier à appeler contenant le code à
montrer.</li>
<li><code>language</code> est le nom du langage cible, tel <code>sh</code>, <code>PHP</code>, <code>python</code>, etc…
<ul>
<li>Pour ne préciser aucun langage en soit, utilisez <code>&quot;&quot;</code></li>
<li><em>deux fois les double quotes</em> -.</li>
</ul>
</li>
</ul>
<hr>
<p>Exemple : Regardez bien, vous en avez un, juste au-dessus… lors de
l&rsquo;appel du premier shortcode concernant ce shortcode !</p>
<h3 id="color">Color</h3>
<p>Un tout petit shortcode pour gérer un bout de texte en couleur… <br>
Néanmoins, pour cela, j&rsquo;ai défini dans ma feuille de style, des types de
couleurs nommées.</p>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/color.html" title="">color</a></p>
</div>

Le shortcode :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">span</span> <span style="color:#ef6155">{{</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Get</span> <span style="color:#06b6ef">0</span> <span style="color:#ef6155">|</span> <span style="color:#06b6ef">printf</span> <span style="color:#ef6155">`</span><span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">%q`</span> <span style="color:#ef6155">|</span> <span style="color:#06b6ef">safeHTMLAttr</span> <span style="color:#ef6155">}}</span>&gt;{{ .Inner }}&lt;/<span style="color:#5bc4bf">span</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode est simple :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; color &#34;css-name&#34; &gt;}}text{{&lt; /color &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>css-name</code> est le nom de la déclaration CSS</li>
<li><code>text</code> est le texte à coloriser</li>
</ul>
<hr>
<p>Exemple : Ceci est un <span class="dark-green">texte vert</span>
,
celui qui suit est <span class="orange">orangé</span>
, cet autre
est <span class="red">rouge</span>
, etc…</p>
<h3 id="file">File</h3>
<p>L&rsquo;inclusion d&rsquo;un exemple de fichier est un dérivé du shortcode <a href="/fr/web/hugo/hugo-shortcodes/#code">code</a>,
mais au lieu de produire un bloc de code précédé d&rsquo;un entête présentant le code,
j&rsquo;appelle un entête qui restitue le nom de fichier tel que désiré.</p>
<p>Donc, basiquement c&rsquo;est le même shortcode que pour code.</p>
<p>De manière plus évolué, cela donne ainsi :
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/file.html" title="">file</a></p>
</div>
</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $name := .Get 0 | safeHTML }}{{ $file := urlize (print &#34;/content/inc/&#34; $name) | readFile }}{{ $lang := .Get 1}}{{ $filename := .Get 2 }}{{  $opt := &#34;linenos=table&#34; }}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;info-file&#34;</span>&gt;&lt;<span style="color:#5bc4bf">p</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;text-white-50&#34;</span>&gt;{{ i18n &#34;fileTitle&#34; }}&lt;<span style="color:#5bc4bf">em</span>&gt;{{ $filename }}&lt;/<span style="color:#5bc4bf">em</span>&gt;&lt;/<span style="color:#5bc4bf">p</span>&gt;&lt;/<span style="color:#5bc4bf">div</span>&gt;&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;code&#34;</span>&gt;{{ highlight $file $lang $opt }}&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; file &#34;example-file&#34; language &#34;filename&#34; &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>/example-file</code> est le nom du fichier à appeler contenant le contenu
d&rsquo;un fichier à montrer.</li>
<li><code>language</code> est le nom du langage cible, tel <code>sh</code>, <code>PHP</code>, <code>python</code>, etc…
<ul>
<li>Pour ne préciser aucun langage en soit, utilisez <code>&quot;&quot;</code></li>
<li><em>deux fois les double quotes</em> -.</li>
</ul>
</li>
<li><code>filename</code> est le nom du fichier - celui qui est affiché.</li>
</ul>
<hr>
<p>Exemple : y&rsquo;a-t-il vraiment besoin encore de le prouver ? Regardez bien
juste au-dessus ;)</p>
<h3 id="image">Image</h3>
<p>Il est vrai que 






















































<abbr lang="en" title="MarkDown">MD</abbr>

























































 a un code prévu pour l&rsquo;inclusion d&rsquo;image, mais
j&rsquo;ai crée ce shortcode pour pouvoir spécifier une taille d&rsquo;image et
renvoyé vers l&rsquo;image source par le biais d&rsquo;un élément 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 <code>a</code>
appliqué sur l&rsquo;élément 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































  <code>img</code>.</p>
<hr>
<h4 id="pngjpgtiff">PNG/JPG/Tiff</h4>
<p>Prenons en considération que les images sont fournies en tant qu&rsquo;assets :</p>
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/img.html" title="">img</a></p>
</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1</span><span>{{/* runner for assets/image */}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2</span><span>{{- $src := resources.Get (printf &#34;%s%s&#34; &#34;/images/&#34; (.Get &#34;s&#34;)) -}}{{- $alt := .Get &#34;a&#34; | safeHTML -}}{{- $width := printf &#34;%s&#34; (.Get &#34;w&#34;) -}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3</span><span>{{- $img := $src -}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4</span><span>{{- with $width -}}{{- $img = $src.Resize (printf &#34;%sx&#34; $width) -}}{{- end -}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5</span><span>{{- with $img -}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6</span><span>&lt;<span style="color:#5bc4bf">figure</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7</span><span>    &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $src.RelPermalink }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $alt }}&#34;</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8</span><span>    &lt;<span style="color:#5bc4bf">picture</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9</span><span>        <span style="color:#776e71">&lt;!-- &lt;source srcset=&#34;/img/.avif&#34; type=&#34;image/avif&#34;&gt; --&gt;</span>
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10</span><span>        {{- with .Resize (printf &#34;%dx%d webp&#34; .Width .Height) }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11</span><span>        &lt;<span style="color:#5bc4bf">source</span> <span style="color:#06b6ef">srcset</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .RelPermalink }}&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;image/webp&#34;</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12</span><span>        {{ end }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13</span><span>        &lt;<span style="color:#5bc4bf">img</span> <span style="color:#06b6ef">alt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $alt }}&#34;</span> <span style="color:#06b6ef">loading</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;lazy&#34;</span> <span style="color:#06b6ef">src</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .RelPermalink }}&#34;</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .MediaType }}&#34;</span> <span style="color:#06b6ef">height</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .Height }}&#34;</span> <span style="color:#06b6ef">width</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .Width }}&#34;</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14</span><span>    &lt;/<span style="color:#5bc4bf">picture</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15</span><span>    &lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16</span><span>    &lt;<span style="color:#5bc4bf">figcaption</span>&gt;{{ $alt }}&lt;/<span style="color:#5bc4bf">figcaption</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17</span><span>&lt;/<span style="color:#5bc4bf">figure</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18</span><span>{{- end -}}
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; img a=&#34;alt&#34; s=&#34;src&#34; w=&#34;width&#34; &gt;}}
</code></pre></div>
</p>
<p>Les paramètres nommés sont :</p>
<ul>
<li><code>a</code> : l&rsquo;équivalent de l&rsquo;attribut <code>alt</code></li>
<li><code>s</code> : l&rsquo;équivalent de l&rsquo;attribut <code>src</code></li>
<li><code>w</code> : l&rsquo;équivalent de l&rsquo;attribut <code>width</code></li>
</ul>
<hr>
<p>Exemple :</p>
<figure>
    <a href="/images/Logo_full_192px.png" title="Mon Logo">
    <picture>
        
        <source srcset="/images/Logo_full_192px_hu_b05553d0fc9bac22.webp" type="image/webp">
        
        <img alt="Mon Logo" height="124" loading="lazy" src="/images/Logo_full_192px_hu_d793f2650db82c05.png" type="image/png" width="124">
    </picture>
    </a>
    <figcaption>Mon Logo</figcaption>
</figure>
<p>Cette image représentant mon logo, ayant pour titre &ldquo;Mon Logo&rdquo;, a une
taille de 192 














































































<span lang="en">px <em>(pixels)</em></span>
































, redimensionnée à la taille de 124 pixels, et
est au format 









































































<span lang="en">PNG <em>(Portable Network Graphics)</em></span>





































.</p>
<h4 id="svg">SVG</h4>
<p>Concernant les images au format 



























































































<span lang="en">SVG <em>(Scalable Vector Graphics)</em></span>



















, je les gère différemment du
précédent shortcode :</p>
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/figure-svg.html" title="">figure-svg</a></p>
</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1</span><span>{{/* runner for assets/svg */}}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2</span><span>{{- $class := .Get &#34;class&#34; -}}{{- $src := resources.Get (printf &#34;%s%s&#34; &#34;/svg/&#34; (.Get &#34;src&#34;)) -}}{{ $title := .Get &#34;title&#34; }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3</span><span>{{ with $src }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4</span><span>&lt;<span style="color:#5bc4bf">figure</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ if $class }}{{ $class }}{{ end }}&#34;</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5</span><span>    &lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ .RelPermalink }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $title }}&#34;</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6</span><span>    {{ .Content | safeHTML }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7</span><span>    &lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8</span><span>    {{ if $title }}&lt;<span style="color:#5bc4bf">figcaption</span> <span style="color:#06b6ef">aria-hidden</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;true&#34;</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;hidden&#34;</span> <span style="color:#06b6ef">hidden</span>&gt;{{ $title }}&lt;/<span style="color:#5bc4bf">figcaption</span>&gt;{{ end }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9</span><span>&lt;/<span style="color:#5bc4bf">figure</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10</span><span>{{ end }}
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; figure-svg class=&#34;class-name&#34; src=&#34;image.svg&#34; title=&#34;the title&#34; &gt;}}
</code></pre></div>
</p>
<hr>
<p>Exemple :


<figure class="pure-img">
    <a href="/svg/Logo_final.svg" title="Mon Logo">
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   id="svg3108"
   version="1.1"
   inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
   sodipodi:docname="Logo_final.svg"
   width="64"
   height="64"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/">
  <sodipodi:namedview
     id="namedview30"
     pagecolor="#ffffff"
     bordercolor="#000000"
     borderopacity="0.25"
     inkscape:showpageshadow="2"
     inkscape:pageopacity="0.0"
     inkscape:pagecheckerboard="0"
     inkscape:deskcolor="#d1d1d1"
     showgrid="false"
     inkscape:zoom="3.0570583"
     inkscape:cx="30.421402"
     inkscape:cy="58.225909"
     inkscape:window-width="1920"
     inkscape:window-height="1031"
     inkscape:window-x="0"
     inkscape:window-y="25"
     inkscape:window-maximized="1"
     inkscape:current-layer="layer1" />
  <title
     id="title853">Logo Emblème Stéphane HUC</title>
  <defs
     id="defs3110" />
  <metadata
     id="metadata3113">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:title>Logo Emblème Stéphane HUC</dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Calque 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0.00367771,-0.00353708)">
    <g
       transform="matrix(0.02413578,0,0,0.02334611,-0.05137015,-0.00127009)"
       style="display:inline"
       id="g4250"
       inkscape:export-filename="/home/zou/Documents/Projets_sur_images/Stephane-huc.net/Logo_original.png"
       inkscape:export-xdpi="300"
       inkscape:export-ydpi="300">
      <g
         id="g3893"
         style="display:inline;fill:#4d4d4d"
         transform="matrix(0.06444778,0,0,0.06450434,865.42675,1541.6735)">
        <path
           inkscape:connector-curvature="0"
           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsssc"
           id="path2385-6-1-2"
           d="m 23774.425,-13094.781 c -407.725,2.746 -749.397,40.026 -972.445,28.012 -4599.937,59.837 -9024.559,3454.6637 -10088.773,4551.7613 -1032.632,1431.3562 -1902.759,4120.4375 -3414.3254,6116.3965 C 7040.4567,1715.9353 4369.202,5321.9681 986.55523,8407.9766 -4389.5849,12448.032 -8602.0428,12402.637 -12768.187,12194.347 c -252.964,17.663 -415.823,306.287 -501.736,508.146 274.498,360.798 549.024,468.121 823.522,457.374 l 2991.3542,-94.976 c 3456.504,-296.023 6332.5254,-987.067 8247.1738,-2331.958 -1416.3389,1353.905 -8714.7449,3661.386 -9866.29,3397.271 -283.94,94.386 -9.166,418.668 -14.627,627.634 443.726,168.12 891.426,312.023 1382.8762,197.395 3340.0325,-1065.466 6699.0628,-1956.661 9899.08747,-4312.462 L -6089.161,17754.195 c -98.5516,407.272 -100.4203,652.783 -4.8749,736.614 l 355.0258,94.104 c 229.6322,33.856 492.0244,-81.828 782.3016,-323.448 L 2012.6316,9672.4329 C 2658.8638,14594.17 7818.5983,15351.227 11738.861,12799.22 l 127.65,-1168.167 C 7834.5326,14914.263 2650.1202,12909.869 3004.5788,9106.5143 L 5888.675,5359.9752 C 6887.5627,4011.8679 8068.294,2775.8085 9455.3418,1667.2698 h 8.8646 C 10742.256,691.78922 12091.181,-25.504325 13349.115,-1036.7181 c 1520.143,-1055.4722 4302.351,-1145.0617 5286.398,-2327.1449 1177.704,-1664.9321 2145.664,-3667.8767 2974.957,-5435.546 1020.536,-2296.596 2897.375,-2743.981 6123.216,-278.3644 -109.42,-1287.3486 -1023.595,-2502.5416 -1546.427,-3009.9256 -1021.529,-829.12 -1603.165,-855.9 -2412.834,-1007.082 z m -34848.588,27224.985 c 1.234,-0.42 2.29,-0.913 3.545,-1.315 h -9.309 c 1.838,0.451 3.895,0.882 5.764,1.315 z m 36292.522,-26286.618 c 206.696,0 374.086,206.617 374.086,461.752 0,255.135 -167.39,462.19 -374.086,462.19 -206.695,0 -374.529,-207.055 -374.529,-462.19 0,-255.135 167.834,-461.752 374.529,-461.752 z"
           style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:21.9289px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
        <g
           transform="matrix(14.180303,0.29145382,-0.29145382,14.180303,39070.285,-17179.84)"
           id="g3323-6-2"
           style="fill:#999999;fill-opacity:1;stroke:#990000;stroke-opacity:1">
          <path
             inkscape:connector-curvature="0"
             style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             d="m -1938.7905,1344.2995 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
             id="path3190-2-0-4"
             sodipodi:nodetypes="cccccccccccccccccccccc" />
          <path
             inkscape:connector-curvature="0"
             style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             d="m -1766.1814,1226.0731 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
             id="path3190-0-8-2-9"
             sodipodi:nodetypes="cccccccccccccccccccccc" />
        </g>
        <g
           id="g3607-7"
           style="fill:#999999;fill-opacity:1;stroke:#990000;stroke-opacity:1"
           transform="matrix(10.256384,0,0,10.256384,27740.017,-9419.2772)">
          <path
             inkscape:connector-curvature="0"
             sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
             id="path2853-1-2-3"
             d="m -3334.7852,-1248.287 c 51.9752,263.91148 364.552,597.09982 649.489,723.58561 186.8994,102.74774 436.9783,80.34473 628.0009,153.0754 176.754,59.99791 336.6065,134.19234 455.7429,223.77162 v 0 c 95.6093,72.55212 166.8615,174.225196 178.8187,313.54167 -21.1645,58.71298 -67.8029,109.93553 -112.5308,161.38138 -108.9474,42.30362 -193.7664,43.94287 -273.1033,40.38991 v 0 c -289.559,-41.98012 -408.6126,-122.75609 -537.4682,-237.26062 -138.9061,-154.600767 -217.6672,-263.90172 -373.9094,-355.18101 -178.3851,-112.57744 -359.9805,-46.07103 -531.5855,-101.08503 -15.4761,-3.45827 -6.3053,-53.81809 36.6639,-43.63616 64.7876,15.3519 174.3223,-1.04389 174.3223,-1.04389 l -79.9048,-49.14253 v 0 l 36.7606,-7.32283 v 0 l 89.4837,49.88512 v 0 l 180.7667,8.58049 v 0 l -95.19,-169.30622 v 0 0 l -44.2175,-2.75208 v 0 l 1.9939,-18.56317 31.584,1.9656 c -91.0217,-150.25746 -222.4184,-249.74105 -339.9897,-366.61111 l 33.2464,-1.66844 v 0 l 33.3433,34.64483 v 0 c -87.3435,-107.03536 -156.5494,-220.39644 -185.2023,-347.90084 5.407,-25.6798 28.4059,-33.5554 42.8852,-9.3477 z"
             style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:3.14969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
          <path
             inkscape:connector-curvature="0"
             sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
             id="path2853-1-8-2-7"
             d="m -3964.5819,579.94648 c 232.1778,142.02444 696.5351,140.75989 988.106,18.70266 205.9526,-66.5673 362.6995,-264.70185 549.2022,-354.76022 167.1463,-88.31108 333.1245,-154.57977 482.3054,-180.583195 v 0 c 120.2135,-20.415854 245.1813,-3.15744 357.0123,83.134705 28.9606,55.52615 34.6919,124.56859 41.9136,192.36665 -44.1007,108.51739 -101.6932,171.65364 -159.3434,227.23914 v 0 c -231.9712,183.0827 -374.5522,215.03066 -548.9965,231.13768 -211.2129,-3.89591 -347.056,-20.86741 -523.2284,31.10727 -207.3545,53.63654 -283.8394,231.78243 -443.7115,319.72853 -13.3008,8.9568 -44.3697,-32.1019 -7.0087,-56.5744 56.3312,-36.899 120.0937,-128.17265 120.0937,-128.17265 l -91.9262,24.90186 v 0 l 20.0462,-31.87375 v 0 l 99.1198,-31.39936 v 0 l 131.7153,-126.31933 v 0 l -191.8305,-45.89202 v 0 0 l -32.7044,30.45368 v 0 l -12.4139,-14.12077 23.3603,-21.75279 c -174.7833,-35.94516 -339.8259,-7.73356 -508.2045,-1.49116 l 21.8121,-25.44723 v 0 l 48.8674,-0.74684 v 0 c -140.1103,-9.1506 -272.3455,-35.87817 -386.9742,-101.90494 -15.3362,-21.4712 -5.2426,-43.65993 22.7879,-37.73352 z"
             style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:3.1754px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
        </g>
      </g>
      <path
         style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.41389px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
         d="m 2394.9999,689.06305 c -26.2769,0.17713 -48.2969,2.58185 -62.6719,1.8069 -296.4557,3.85975 -581.6127,222.84081 -650.199,293.60838 -66.5508,92.32867 -122.6286,265.78617 -220.0457,394.53417 -145.5504,265.4061 -317.7069,498.0109 -535.71096,697.0718 -346.48036,260.6012 -617.96395,257.673 -886.462661,244.2374 -16.303005,1.1393 -26.798914,19.7568 -32.3357924,32.7776 17.6907774,23.2731 35.3833394,30.1959 53.0741824,29.5026 l 192.786151,-6.1263 c 222.76402,-19.0948 408.11723,-63.6701 531.51204,-150.4215 -91.27986,87.3328 -561.64597,236.1754 -635.8605,219.1388 -18.29929,6.0883 -0.59073,27.0059 -0.94272,40.4851 28.59717,10.8445 57.45048,20.1269 89.12335,12.7328 215.25769,-68.7271 431.73976,-126.2131 637.97425,-278.1725 L 470.3581,2678.956 c -6.35143,26.2709 -6.47187,42.1074 -0.31418,47.5149 l 22.88063,6.0701 c 14.79923,2.1838 31.70983,-5.2783 50.41755,-20.8638 l 449.15854,-554.0299 c 41.64826,317.4734 374.18176,366.3069 626.83396,201.6913 l 8.2267,-75.3518 c -259.852,211.7813 -593.9759,82.4892 -571.1318,-162.8437 l 185.8736,-241.6681 c 64.3761,-86.9587 140.4715,-166.6899 229.8637,-238.1955 h 0.5713 c 82.3675,-62.9228 169.3027,-109.1913 250.3737,-174.419 97.9699,-68.0825 277.277,-73.8615 340.6967,-150.111 75.9004,-107.3953 138.2833,-236.5939 191.7294,-350.61629 65.7712,-148.14043 186.7294,-176.9987 394.6277,-17.95572 -7.0519,-83.03958 -65.9685,-161.4248 -99.6638,-194.15328 -65.8353,-53.48184 -103.3205,-55.20926 -155.5019,-64.96116 z M 149.08576,2445.1929 c 0.0795,-0.027 0.14754,-0.059 0.22845,-0.085 h -0.59993 c 0.11845,0.029 0.25098,0.057 0.37148,0.085 z M 2488.0583,749.5918 c 13.3211,0 24.109,13.32769 24.109,29.78501 0,16.45732 -10.7879,29.81326 -24.109,29.81326 -13.321,0 -24.1375,-13.35594 -24.1375,-29.81326 0,-16.45732 10.8165,-29.78501 24.1375,-29.78501 z"
         id="path2385-6-1-2-3"
         sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsssc"
         inkscape:connector-curvature="0" />
      <g
         style="display:inline;fill:#999999;fill-opacity:1;stroke:#990000;stroke-opacity:1"
         id="g3323-6-2-4"
         transform="matrix(0.91388911,0.01880004,-0.01878355,0.91469117,3380.7843,425.559)">
        <path
           sodipodi:nodetypes="cccccccccccccccccccccc"
           id="path3190-2-0-4-2"
           d="m -1938.7905,1344.2995 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
           style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
           inkscape:connector-curvature="0" />
        <path
           sodipodi:nodetypes="cccccccccccccccccccccc"
           id="path3190-0-8-2-9-5"
           d="m -1766.1814,1226.0731 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
           style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
           inkscape:connector-curvature="0" />
      </g>
      <path
         inkscape:connector-curvature="0"
         sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
         id="path2853-1-2-3-9"
         d="m 1071.448,12.565243 c -15.3369,146.179207 73.828,372.947977 180.7482,487.459287 67.2709,85.4026 180.411,116.49879 253.836,186.99056 68.9967,61.4286 128.5121,127.35333 167.9088,194.3213 v 0 c 31.5208,54.088 48.125,119.16171 33.2259,193.68211 -17.7944,26.9261 -45.6999,45.6007 -72.7982,64.718 -53.9976,3.3831 -91.5092,-10.2639 -125.8605,-25.6749 v 0 C 1387.3321,1042.7224 1346.6981,980.34835 1306.6359,898.75209 1267.9574,794.5785 1249.1568,724.2529 1193.6994,650.05735 1131.5923,560.99655 1042.1677,564.5514 974.71289,506.59578 c -6.30086,-4.44472 5.01449,-29.07557 22.42474,-16.43307 26.25067,19.06189 76.75837,29.25724 76.75837,29.25724 l -28.0058,-39.22499 v 0 l 17.2141,2.47464 v 0 l 32.108,41.24885 v 0 l 78.1981,35.36579 v 0 l -17.3399,-104.35052 v 0 0 l -19.0336,-8.99068 v 0 l 3.5616,-9.31623 13.5954,6.42185 c -18.2636,-93.72824 -61.6156,-167.94463 -96.3766,-248.84241 l 14.8517,4.81539 v 0 l 9.6413,23.72335 v 0 c -22.9001,-70.61432 -36.914,-141.418612 -31.0608,-212.64819 6.091,-12.4349571 17.3374,-12.6004057 20.1985,2.468443 z"
         style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:1.58535px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
      <path
         inkscape:connector-curvature="0"
         sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
         id="path2853-1-8-2-7-4"
         d="m 346.99101,968.42886 c 122.89969,124.43284 416.59744,198.91414 621.36814,171.56464 141.34235,-7.3092 273.67225,-103.0072 406.66535,-127.8264 120.466,-26.88812 236.4935,-40.49317 335.1448,-32.21014 v 0 c 79.4054,7.00369 155.4909,37.80454 211.6845,108.67004 8.9823,38.6312 1.014,81.759 -5.8034,124.3677 -46.0902,59.1793 -93.0891,88.4349 -138.8571,113.0661 v 0 c -177.3468,74.3073 -272.8249,70.7271 -385.7821,52.3012 -132.8378,-36.6106 -215.845,-68.9985 -335.9157,-65.7821 -140.05758,-0.8213 -218.30441,95.6669 -334.11166,123.5108 -9.91006,3.3189 -22.65364,-26.8114 5.06783,-35.7143 41.79723,-13.4237 97.41938,-58.8771 97.41938,-58.8771 l -62.28015,0.3225 v 0 l 18.02055,-16.2327 v 0 l 67.9175,-3.1279 v 0 l 104.45336,-55.8609 v 0 l -113.53757,-59.1376 v 0 0 l -25.78236,13.3133 v 0 l -5.4754,-10.6425 18.41603,-9.5096 c -104.43314,-50.2954 -213.48017,-59.7993 -320.94769,-83.2716 l 18.0578,-12.0185 v 0 l 31.01082,7.463 v 0 c -87.0171,-28.2993 -166.10614,-66.0655 -227.47003,-124.99811 -6.08836,-15.60868 4.01601,-27.53473 20.7371,-19.36983 z"
         style="display:inline;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:#990000;stroke-width:2.04192px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
      <g
         id="g2901"
         style="display:inline;fill:#990000;fill-opacity:1;stroke:#800000"
         inkscape:export-filename="/home/zou/Documents/Projets_sur_images/Stephane-huc.net/Logo_gris_999999_390px.png"
         inkscape:export-xdpi="90"
         inkscape:export-ydpi="90"
         transform="matrix(0.66100118,0,0,0.66158128,2645.7866,917.11829)">
        <path
           style="display:inline;fill:#990000;fill-opacity:1;fill-rule:evenodd;stroke:#800000;stroke-width:2.13807px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
           d="m -386.64618,-358.3625 c -39.7533,0.2677 -73.0664,3.9025 -94.8137,2.7311 -448.495,5.8342 -879.89672,336.83061 -983.65782,443.797906 -100.6819,139.557584 -185.5195,401.743684 -332.8976,596.350184 -220.197,401.16931 -480.645,752.75841 -810.4539,1053.64501 -524.175,393.9064 -934.8907,389.4804 -1341.0908,369.1721 -24.6641,1.7221 -40.5428,29.863 -48.9194,49.5443 26.7636,35.1779 53.53,45.6419 80.2936,44.5941 l 291.6578,-9.2602 c 337.01,-28.8623 617.4228,-96.2393 804.1015,-227.3665 -138.0934,132.0061 -849.6898,356.9861 -961.9657,331.2348 -27.6843,9.2027 -0.8937,40.8202 -1.4262,61.1945 43.2634,16.3917 86.9143,30.4223 134.8308,19.246 325.654,-103.8832 653.1603,-190.7749 965.1635,-420.4661 l -612.5292,693.3656 c -9.6088,39.7091 -9.791,63.6465 -0.4753,71.8201 l 34.6151,9.1751 c 22.3892,3.301 47.9725,-7.9782 76.2746,-31.5362 l 679.5124,-837.4328 c 63.0078,479.8706 566.0832,553.6838 948.3098,304.8625 l 12.4459,-113.8966 c -393.1189,320.1138 -898.6004,124.6849 -864.0406,-246.1431 l 281.2001,-365.2885 c 97.3918,-131.4408 212.5134,-251.9569 347.7509,-360.0397 h 0.8643 c 124.6102,-95.1096 256.1307,-165.0459 378.7796,-263.6395 148.2143,-102.9088 419.48022,-111.6438 515.42512,-226.8972 114.8264,-162.3313 209.2027,-357.6189 290.059,-529.967097 99.5025,-223.918703 282.4948,-267.538803 597.0151,-27.1406 -10.6685,-125.5168 -99.8008,-243.998403 -150.777,-293.468503 -99.5993,-80.8394 -156.309,-83.4505 -235.2519,-98.1907 z M -3784.3922,2296.0803 c 0.1203,-0.041 0.2232,-0.089 0.3456,-0.1282 h -0.9076 c 0.1792,0.044 0.3797,0.086 0.562,0.1282 z M -245.86228,-266.8715 c 20.1529,0 36.4735,20.1452 36.4735,45.0209 0,24.8757 -16.3206,45.0637 -36.4735,45.0637 -20.1528,0 -36.5167,-20.188 -36.5167,-45.0637 0,-24.8757 16.3639,-45.0209 36.5167,-45.0209 z"
           id="path2385-6-1"
           sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccsssc"
           inkscape:connector-curvature="0" />
        <g
           style="fill:#990000;fill-opacity:1;stroke:#800000"
           id="g3323-6"
           transform="matrix(1.3825831,0.02841682,-0.02841682,1.3825831,1104.704,-756.6568)">
          <path
             sodipodi:nodetypes="cccccccccccccccccccccc"
             id="path3190-2-0"
             d="m -1938.7905,1344.2995 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
             style="display:inline;fill:#990000;fill-opacity:1;fill-rule:evenodd;stroke:#800000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             inkscape:connector-curvature="0" />
          <path
             sodipodi:nodetypes="cccccccccccccccccccccc"
             id="path3190-0-8-2"
             d="m -1766.1814,1226.0731 15.3955,-1.283 7.0562,-10.2637 -3.8488,-8.9807 3.8488,-8.9808 c 26.901,-8.9122 44.2829,-1.9591 55.8088,14.754 -0.1027,10.6945 -8.3234,15.9763 -18.6029,19.8859 -6.7082,-0.016 -14.6164,2.0346 -17.3412,-4.8053 v 0 c -16.1045,-1.7244 -11.7855,6.9433 -12.7007,9.072 3.8166,4.6142 10.3634,8.3754 23.8137,9.979 -7.6533,3.5761 -11.6619,14.8063 -24.7209,7.0307 -5.8792,-4.5108 -13.9229,-4.3322 -16.5562,-15.8758 -13.5829,-3.7285 -14.572,5.856 -14.515,11.1131 -0.352,5.6108 2.6918,10.0899 5.8967,14.5151 18.6918,9.7777 28.4118,11.6393 36.968,12.4739 11.2194,0.8225 24.7349,-15.9588 37.6483,-28.123 11.7646,0.4051 16.4086,-11.0571 23.1335,-19.0511 6.177,-27.5232 -20.7198,-44.6944 -30.8445,-51.7098 -19.6553,-8.2012 -39.8866,-7.5233 -50.5759,-3.6288 -9.4566,6.292 -15.9533,13.324 -23.1334,20.1851 -3.7507,11.7151 -4.9786,23.178 3.27,33.6932 z"
             style="display:inline;fill:#990000;fill-opacity:1;fill-rule:evenodd;stroke:#800000;stroke-width:1.55587px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             inkscape:connector-curvature="0" />
        </g>
        <g
           style="fill:#990000;fill-opacity:1;stroke:#800000"
           id="g3607">
          <path
             style="display:inline;fill:#990000;fill-opacity:1;fill-rule:evenodd;stroke:#800000;stroke-width:3.14969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             d="m -3334.7852,-1248.287 c 51.9752,263.91148 364.552,597.09982 649.489,723.58561 186.8994,102.74774 436.9783,80.34473 628.0009,153.0754 176.754,59.99791 336.6065,134.19234 455.7429,223.77162 v 0 c 95.6093,72.55212 166.8615,174.225196 178.8187,313.54167 -21.1645,58.71298 -67.8029,109.93553 -112.5308,161.38138 -108.9474,42.30362 -193.7664,43.94287 -273.1033,40.38991 v 0 c -289.559,-41.98012 -408.6126,-122.75609 -537.4682,-237.26062 -138.9061,-154.600767 -217.6672,-263.90172 -373.9094,-355.18101 -178.3851,-112.57744 -359.9805,-46.07103 -531.5855,-101.08503 -15.4761,-3.45827 -6.3053,-53.81809 36.6639,-43.63616 64.7876,15.3519 174.3223,-1.04389 174.3223,-1.04389 l -79.9048,-49.14253 v 0 l 36.7606,-7.32283 v 0 l 89.4837,49.88512 v 0 l 180.7667,8.58049 v 0 l -95.19,-169.30622 v 0 0 l -44.2175,-2.75208 v 0 l 1.9939,-18.56317 31.584,1.9656 c -91.0217,-150.25746 -222.4184,-249.74105 -339.9897,-366.61111 l 33.2464,-1.66844 v 0 l 33.3433,34.64483 v 0 c -87.3435,-107.03536 -156.5494,-220.39644 -185.2023,-347.90084 5.407,-25.6798 28.4059,-33.5554 42.8852,-9.3477 z"
             id="path2853-1-2"
             sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
             inkscape:connector-curvature="0" />
          <path
             style="display:inline;fill:#990000;fill-opacity:1;fill-rule:evenodd;stroke:#800000;stroke-width:3.1754px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
             d="m -3964.5819,579.94648 c 232.1778,142.02444 696.5351,140.75989 988.106,18.70266 205.9526,-66.5673 362.6995,-264.70185 549.2022,-354.76022 167.1463,-88.31108 333.1245,-154.57977 482.3054,-180.583195 v 0 c 120.2135,-20.415854 245.1813,-3.15744 357.0123,83.134705 28.9606,55.52615 34.6919,124.56859 41.9136,192.36665 -44.1007,108.51739 -101.6932,171.65364 -159.3434,227.23914 v 0 c -231.9712,183.0827 -374.5522,215.03066 -548.9965,231.13768 -211.2129,-3.89591 -347.056,-20.86741 -523.2284,31.10727 -207.3545,53.63654 -283.8394,231.78243 -443.7115,319.72853 -13.3008,8.9568 -44.3697,-32.1019 -7.0087,-56.5744 56.3312,-36.899 120.0937,-128.17265 120.0937,-128.17265 l -91.9262,24.90186 v 0 l 20.0462,-31.87375 v 0 l 99.1198,-31.39936 v 0 l 131.7153,-126.31933 v 0 l -191.8305,-45.89202 v 0 0 l -32.7044,30.45368 v 0 l -12.4139,-14.12077 23.3603,-21.75279 c -174.7833,-35.94516 -339.8259,-7.73356 -508.2045,-1.49116 l 21.8121,-25.44723 v 0 l 48.8674,-0.74684 v 0 c -140.1103,-9.1506 -272.3455,-35.87817 -386.9742,-101.90494 -15.3362,-21.4712 -5.2426,-43.65993 22.7879,-37.73352 z"
             id="path2853-1-8-2"
             sodipodi:nodetypes="ccccccccccccsccccccccccccccccccccccc"
             inkscape:connector-curvature="0" />
        </g>
      </g>
    </g>
  </g>
</svg>

    </a>
    <figcaption aria-hidden="true" class="hidden" hidden>Mon Logo</figcaption>
</figure>

</p>
<hr>
<h3 id="kbd">kbd</h3>
<p>Ce shortcode est utilisé pour la gestion de l&rsquo;élément 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 <code>kbd</code>.</p>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/kbd.html" title="">kbd</a></p>
</div>

Le shortcode :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $k := .Get 0 | safeHTML }}&lt;<span style="color:#5bc4bf">kbd</span>&gt;{{ $k }}&lt;/<span style="color:#5bc4bf">kbd</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shorcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; kbd key &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>key</code> est le nom de la touche clavier !</li>
</ul>
<hr>
<p>Exemple : voici le rendu de la touche <kbd>A</kbd>
 !</p>
<h3 id="lien-interne">Lien interne</h3>
<p>Ce shortcode a deux versions légérement différentes. J&rsquo;ai commencé avec
<a href="/fr/web/hugo/hugo-shortcodes/#inside-v1">la première</a>, puis un jour, je me suis demandé comment faire pour
&ldquo;injecter&rdquo; aussi le nom d&rsquo;une ancre ; <a href="/fr/web/hugo/hugo-shortcodes/#inside-v2">la v2</a> est née !</p>
<h4 id="inside-v1">Inside v1</h4>
<p>Pour gérer les liens internes entre les pages de ce site, je me suis
évertué à mettre en place le shortcode suivant :</p>
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/inside.html" title="">inside</a></p>
</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1</span><span>{{ $link := .Get 0 }}{{ $link := replace $link &#34;:&#34; &#34;/&#34; }}{{ $url := (print ( relLangURL $link ) &#34;/&#34;) }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2</span><span>{{ if .Get 1 }}{{ $txt := .Get 1 }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3</span><span>&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;inside&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $url }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">lnkInsideTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#06b6ef">with</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Site</span><span style="color:#ef6155">.</span><span style="color:#06b6ef">GetPage</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">link</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Title</span> <span style="color:#ef6155">}}{{</span> <span style="color:#06b6ef">end</span> <span style="color:#ef6155">}}&#34;</span>&gt;{{ $txt }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4</span><span>{{ else }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5</span><span>{{ with .Site.GetPage $link }}{{ $title := .Title }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;inside&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $url }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">lnkInsideTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">title</span> <span style="color:#ef6155">}}&#34;</span>&gt;{{ $title }}&lt;/<span style="color:#5bc4bf">a</span>&gt;{{ end }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6</span><span>{{ end }}
</span></span></code></pre></div><p>De même, j&rsquo;ai créé une définition 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, nommée <code>inside</code>, qui me
permet de modifier légérement le rendu pour les liens internes.</p>
<hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; inside &#34;section:subsection:pagename&#34; &#34;Title&#34; &gt;}}
</code></pre></div>
</p>
<ul>
<li>les noms de sections et pages sont séparés par un <code>:</code></li>
<li>Le titre peut être omis, dans ce cas-là sera affiché celui de la page
appelée.</li>
</ul>
<hr>
<p>Exemples :</p>
<ul>
<li>Là, j&rsquo;appelle la page 
<a class="inside" href="/fr/web/hugo/hugo-deploy/" title="Lien interne vers l&#39;article : 'Hugo : Déploiement SFTP'">Hugo : Déploiement SFTP</a>

 et c&rsquo;est
son titre qui est fourni, ainsi que l&rsquo;







































































































<span lang="en">URL <em>(Uniform Resource Locator)</em></span>







 adéquate</li>
<li>Dans cet exemple, je force le titre dans l&rsquo;appel de ma page

    <a class="inside" href="/fr/web/hugo/hugo-deploy/" title="Lien interne vers l&#39;article : 'Hugo : Déploiement SFTP'">Déploiement d&#39;un site statique par Hugo</a>
</li>
</ul>
<h4 id="inside-v2">Inside v2</h4>
<p>Cette version est subtilement différente :</p>
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/inside2.html" title="">inside2</a></p>
</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1</span><span>{{ $link := .Get &#34;l&#34; }}{{ $link := replace $link &#34;:&#34; &#34;/&#34; }}{{ $url := (print ( relLangURL $link ) &#34;/&#34;) }}{{ $anchor := .Get &#34;a&#34; }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2</span><span>{{ if .Get &#34;t&#34; }}{{ $txt := .Get &#34;t&#34; }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;inside&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $url }}{{ if $anchor }}#{{ $anchor }}{{ end }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">lnkInsideTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#39;{{</span> <span style="color:#06b6ef">with</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Site</span><span style="color:#ef6155">.</span><span style="color:#06b6ef">GetPage</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">link</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">.</span><span style="color:#06b6ef">Title</span> <span style="color:#ef6155">}}{{</span> <span style="color:#06b6ef">end</span> <span style="color:#ef6155">}}&#39;&#34;</span>&gt;{{ $txt }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3</span><span>{{ else }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4</span><span>{{ with .Site.GetPage $link }}{{ $title := .Title }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;inside&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $url }}{{ if $anchor }}#{{ $anchor }}{{ end }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">lnkInsideTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}&#39;{{</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">title</span> <span style="color:#ef6155">}}&#39;&#34;</span>&gt;{{ $title }}&lt;/<span style="color:#5bc4bf">a</span>&gt;{{ end }}
</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5</span><span>{{ end }}
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; inside2 l=&#34;section:subsection:pagename&#34; t=&#34;title&#34; a=&#34;anchor-name&#34; &gt;}}
</code></pre></div>
</p>
<p>Les paramètres nommés sont :</p>
<ul>
<li><code>a</code> : cible une ancre dans le document appelé ; bien-sûr, cette ancre
doit exister… dans le document en question. Peut-être omise !</li>
<li><code>l</code> : nom du lien interne ; les noms de sections et pages sont séparés
par le symbole <code>:</code></li>
<li><code>t</code> : le titre. Peut être omis, dans ce cas-là sera affiché celui de
la page appelée.</li>
</ul>
<hr>
<p>Exemple :</p>
<ul>
<li>Là, j&rsquo;appelle la page <a class="inside" href="/fr/web/hugo/hugo-deploy/#rsync" title="Lien interne vers l&#39;article : 'Hugo : Déploiement SFTP'">Hugo : Déploiement SFTP</a>
; c&rsquo;est son titre qui est fourni, ainsi que l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







 adéquate,
mais elle pointe vers le chapitre <strong>rsync</strong>, ciblée par l&rsquo;ancre correspondante.</li>
<li>Dans cet exemple, je force le titre dans l&rsquo;appel de ma page
<a class="inside" href="/fr/web/hugo/hugo-deploy/" title="Lien interne vers l&#39;article : 'Hugo : Déploiement SFTP'">Déploiement d'un site statique par Hugo</a>

mais je ne cible pas d&rsquo;ancre.</li>
</ul>
<h3 id="note">Note</h3>
<p>Les blocs d&rsquo;alertes ou de notes sont des blocs de code 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>



















































































présentant un texte et mis en valeur selon un identifiant, qui est traduit
selon la langue utilisée.</p>
<p>La valeur de cet identifiant peut être :</p>
<ul>
<li><code>danger</code> pour afficher une alerte de type &lsquo;danger&rsquo; qui aura une teinte
rougée</li>
<li><code>info</code> pour afficher un message de type &lsquo;information&rsquo; qui aura une
teinte bleutée</li>
<li><code>success</code> pour afficher un message de type &lsquo;succès&rsquo; qui aura une
teinte verte</li>
<li><code>tip</code> pour afficher un message de type &lsquo;astuce&rsquo; qui aura une teinte
jaune.</li>
<li><code>warning</code> pour afficher un message de type &lsquo;attention&rsquo; qui aura une
teinte orangée, jaunâtre.</li>
</ul>
<p>Bien-sûr, ces teintes dépendent des déclarations 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































.</p>
<p>Le shortcode en lui-même :</p>
<div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/note.html" title="">note</a></p>
</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $class := .Get 0 }}{{ $wrd := T (printf &#34;alert-%s&#34; $class) }}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;info-tab {{ $class }}-icon&#34;</span>&gt;{{ $wrd }}&lt;/<span style="color:#5bc4bf">div</span>&gt;&lt;<span style="color:#5bc4bf">div</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;alert alert-{{ $class }}&#34;</span> <span style="color:#06b6ef">role</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;alert&#34;</span>&gt;{{ .Inner | .Page.RenderString }}&lt;/<span style="color:#5bc4bf">div</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode est :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; note id &gt;}}
Ceci est un message
{{&lt; /note &gt;}}
</code></pre></div>
</p>
<hr>
<p>Exemples :</p>
<p>
<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>ATTENTION</strong> : Ceci est un message d&rsquo;avertissement pour présenter un danger !</div>

<em>Cet exemple embarque le code MD pour mettre en gras le mot &lsquo;ATTENTION&rsquo;.</em></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ceci est une <strong>note d&rsquo;information</strong>. Merci d&rsquo;en tenir compte ! :D</div>


<div class="tab-info i-success">Succès</div><div class="alert alert-success" role="alert">Vous avez réussi le test ! Soyez heureux…</div>


<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Ce message est une astuce à mettre en valeur. Retenez-la, elle peut vous
être pratique !</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Veuillez prêter attention à ce message ; il semble qu&rsquo;un dysfonctionnement
se prépare. Veuillez faire les tests adéquats.</div>

<h3 id="tag">Tag</h3>
<p>Ce shortcode n&rsquo;existe pas pour gérer les tags générés par Hugo, mais pour
gérer l&rsquo;URL d&rsquo;un tag au sein d&rsquo;une page 






















































<abbr lang="en" title="MarkDown">MD</abbr>

























































. Le shortcode va
générer un élément 





























<abbr lang="en" title="HyperText Markup Language">HTML</abbr>


















































































 <code>a</code> adéquat. Il tient compte de la
gestion multilangue du site.</p>
<p>Au sein de la page Markdown, j&rsquo;intégre un mot qui se veut être un renvoi
vers la page tag ad hoc.</p>
<p>Côté 











<abbr lang="en" title="Cascade Style Sheet">CSS</abbr>




































































































, j&rsquo;ai défini l&rsquo;attribut <code>::after</code> sur la définition
<code>.tag</code> pour ajouter l&rsquo;information <code>(tag)</code> précédé du terme en question.
Ce qui permet visuellement de le différencier des autres liens.</p>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/tag.html" title="">tag</a></p>
</div>

Le shortcode :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $txt := .Get 0 }}{{ $href := &#34;/&#34; | relLangURL}}{{ $href := (printf &#34;%s%s%s&#34; $href &#34;/tags/&#34; $txt) | urlize }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;tag&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $href }}&#34;</span>&gt;{{ $txt }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span></code></pre></div><hr>
<p>L&rsquo;appel du shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; tag tag-name &gt;}}
</code></pre></div>
</p>
<hr>
<p>Exemple : le mot <a class="tag" href="/fr/tags/hugo">Hugo</a>
 est un  lien vers l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







 des
articles contenant le tag &ldquo;Hugo&rdquo;.</p>
<h2 id="autres-shortcodes">Autres shortcodes</h2>
<h3 id="gohugo">GoHugo</h3>
<p>Pour faire un lien vers la documentation officielle d&rsquo;Hugo, je me suis
amusé à écrire ce shortcode :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; gohugo n=&#34;pagename&#34; s=&#34;section&#34; a=&#34;anchor-name&#34; &gt;}}
</code></pre></div>
</p>
<ul>
<li><code>n</code> est le nom de la page dans la documentation du site Gohugo.io</li>
<li><code>s</code> est le nom de la section dans la documentation du site Gohugo.io</li>
<li><code>a</code> est le nom de l&rsquo;ancre à cibler dans la page</li>
</ul>
<hr>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/gohugo.html" title="">gohugo</a></p>
</div>

Le shortcode est :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $section := .Get &#34;s&#34; }}{{ $name := .Get &#34;n&#34; }}{{ $anchor := .Get &#34;a&#34; }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://gohugo.io/{{ $section }}/{{ $name }}/{{ if $anchor }}#{{ $anchor}}{{ end }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">shortcodeGoHugoTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#06b6ef">humanize</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">section</span> <span style="color:#ef6155">}}</span> <span style="color:#ef6155">&amp;</span><span style="color:#06b6ef">gt</span><span style="color:#ef6155">;</span> <span style="color:#ef6155">{{</span> <span style="color:#06b6ef">humanize</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">name</span> <span style="color:#ef6155">}}&#34;</span>&gt;{{ i18n &#34;shortcodeGoHugoDocTitle&#34; }}{{ humanize $section }} &amp;gt; {{ humanize $name }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span></code></pre></div><hr>
<p>Exemple: Le lien vers la page <a href="https://gohugo.io/content-management/shortcodes/" title="Lien vers la page du site officiel Hugo : Content management &gt; Shortcodes">Hugo Documentation : Content management &gt; Shortcodes</a>
 Hugo.</p>
<p>Voici le shortcode correspondant :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; gohugo n=&#34;shortcodes&#34; s=&#34;content-management&#34; &gt;}}
</code></pre></div>
</p>
<h3 id="manpage">Manpage</h3>
<p>Utilisant souvent des renvois vers les manpages officiels d&rsquo;OpenBSD, je
me suis crée le shortcode suivant :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; man title digit anchor &gt;}}
</code></pre></div>
</p>
<ul>
<li>
<p>Si un chiffre <em>(<code>digit</code>)</em> est fourni, le shortcode le restituera à la fois,
dans l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







 reconstituée, que dans le texte affiché. <br>
Dans l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







, ce sera de type <code>txt.digit</code> ; le texte affiché
aura le chiffre entouré des parenthèses, tel que <code>txt(digit)</code>.</p>
</li>
<li>
<p>Si une ancre <em>(<code>anchor</code>)</em> est fournie, le shortcode la restituera à la fois,
dans l&rsquo;








































































































<abbr lang="en" title="Uniform Resource Locator">URL</abbr>







 reconstituée, que dans le texte affiché, tel que
<code>txt(digit)#anchor</code>.</p>
</li>
</ul>
<hr>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/man.html" title="">man</a></p>
</div>

Le shortcode est :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $txt := .Get 0 }}{{ $nb := .Get 1}}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">class</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;man&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://man.openbsd.org/{{ $txt }}{{ if $nb }}{{ print &#34;</span><span style="color:#ef6155">.&#34;</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">nb</span> <span style="color:#ef6155">}}{{</span> <span style="color:#06b6ef">end</span> <span style="color:#ef6155">}}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ i18n &#34;</span><span style="color:#06b6ef">manpageTitle</span><span style="color:#ef6155">&#34;</span> <span style="color:#ef6155">}}{{</span> <span style="color:#ef6155">$</span><span style="color:#06b6ef">txt</span> <span style="color:#ef6155">}}&#34;</span>&gt;{{ $txt }}{{ if $nb }}{{ print &#34;(&#34; $nb &#34;)&#34; }}{{ end }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span></code></pre></div><hr>
<p>Exemples :</p>
<ul>
<li>Lien vers le manpage <strong>Packet Filter</strong> : 
<a class="man" href="https://man.openbsd.org/pf.4" title="Page du Manuel OpenBSD pour : pf">pf(4)</a>
</li>
<li>Autre lien celui vers : 
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
</li>
<li>Un dernier pour la route vers : 
<a class="man" href="https://man.openbsd.org/man" title="Page du Manuel OpenBSD pour : man">man</a>
</li>
</ul>
<h3 id="wikipedia">Wikipedia</h3>
<p>De même pour l&rsquo;encyclopédie Wikipédia, le shortcode créé est le suivant :
<div class="info-code">
    <p>Code :&nbsp;<em>shortcode</em></p>
</div>
<div class="code"><pre tabindex="0"><code class="language-shortcode" data-lang="shortcode">
{{&lt; wp &#34;url-article&#34; &gt;}}
</code></pre></div>
</p>
<hr>
<p><div class="is-right">
    <p class="is-italic is-white-50">Source brute vers le shortcode : <a class="raw-src" href="https://framagit.org/sh-web/hugo/doc.huc.fr.eu.org/-/tree/master/layouts/shortcodes/wp.html" title="">wp</a></p>
</div>

Le shortcode est :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $txt := .Get 0 }}{{ $title := print (i18n &#34;wpTitleArticle&#34;) $txt }}&lt;<span style="color:#5bc4bf">a</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://{{ .Site.Language.Lang }}.wikipedia.org/wiki/{{ $txt }}&#34;</span> <span style="color:#06b6ef">title</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{{ $title }}&#34;</span>&gt;Wikipedia :: {{ $txt }}&lt;/<span style="color:#5bc4bf">a</span>&gt;
</span></span></code></pre></div><hr>
<p>Exemples :</p>
<ul>
<li>Voici un article de promotion sur <a href="https://fr.wikipedia.org/wiki/OpenBSD" title="Article Wikipédia : OpenBSD">OpenBSD <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li>En voici un autre pour <a href="https://fr.wikipedia.org/wiki/Debian" title="Article Wikipédia : Debian">Debian <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li>Et, un troisième un peu plus compliqué : <a href="https://fr.wikipedia.org/wiki/Pare-feu_%28informatique%29" title="Article Wikipédia : Pare-feu_(informatique)">Pare-feu_(informatique) <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<h2 id="ailleurs">Ailleurs</h2>
<p>Pour finir, n&rsquo;hésitez pas à vous amuser avec les shortcodes, faites-vous
aider sur le <a href="https://discourse.gohugo.io/" rel="external">forum de la communauté</a>,
<em>malheureusement pour nous francoph(on|il)es</em>, en anglais.</p>
<ul>
<li><a href="https://after-dark.habd.as/shortcode/" rel="external">https://after-dark.habd.as/shortcode/</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Présentation des différents shortcodes Hugo utilisés sur ce site, fabriqués par mes soins]]></summary>
        <published>2019-11-29T15:29:59+01:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e27f9a31-a6e3-be71-296f-e2f13e56aa77</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/hugo/hugo-deploy/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Hugo : Déploiement SFTP</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Hugo" scheme="http://doc.huc.fr.eu.org/fr/tags/hugo/" />
        <category term="deploy" scheme="http://doc.huc.fr.eu.org/fr/tags/deploy/" />
        <category term="chroot" scheme="http://doc.huc.fr.eu.org/fr/tags/chroot/" />
        <category term="lftp" scheme="http://doc.huc.fr.eu.org/fr/tags/lftp/" />
        <category term="rclone" scheme="http://doc.huc.fr.eu.org/fr/tags/rclone/" />
        <category term="rsync" scheme="http://doc.huc.fr.eu.org/fr/tags/rsync/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="SFTP" scheme="http://doc.huc.fr.eu.org/fr/tags/sftp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Pour déployer un site fait avec le générateur de site statique <strong>Hugo</strong>,
il existe plusieurs solutions :</p>
<ul>
<li>
<p>la plus simple est l&rsquo;usage de l&rsquo;outil <a href="/fr/web/hugo/hugo-deploy/#rsync">rsync</a>.</p>
</li>
<li>
<p>Il existe des &ldquo;solutions&rdquo; de déploiement selon le type de services que
vous utilisez.</p>
</li>
<li>
<p>je vais vous en présenter une troisième solution tenant compte du fait
que votre utilisateur SSH soit soumis au chroot 
























































































<span lang="en">SSH <em>(Secure SHell)</em></span>






















.</p>
</li>
</ul>
<p>Dans le contexte de déploiement &ldquo;simple&rdquo;, il suffit de créer le script de
déploiement nommé <code>deploy</code> à la racine du projet Hugo !</p>
<h2 id="utilisation">Utilisation</h2>
<h3 id="rsync">rsync</h3>
<p>Déployer un site avec <code>rsync</code> est très simple. <strong>rsync</strong> est l&rsquo;outil pour
de la synchronisation de données ; il le fait, et il le fait bien.</p>
<p>Après avoir installé l&rsquo;outil :</p>
<ul>
<li>sous Debian/*Buntu : <code>:# apt install rsync</code></li>
<li>sous OpenBSD : <code>:# pkg_add rsync</code> - <em>pour information, depuis OpenBSD v6.5,
il existe nativement dans le système de base, l&rsquo;outil <code>openrsync</code> ;
reproduisant le comportement de <strong>rsync</strong>, il est asujetti au même problème
décrit ci-dessous</em> -</li>
</ul>
<p>En assumant le fait que vous avez une authentification 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 sur le
serveur où vous désirez vous synchroniser, et mieux une authentification par
clé 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">user</span><span style="color:#5bc4bf">=</span>userid
</span></span><span style="display:flex;"><span><span style="color:#ef6155">host</span><span style="color:#5bc4bf">=</span>servername
</span></span><span style="display:flex;"><span><span style="color:#ef6155">port</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_dist</span><span style="color:#5bc4bf">=</span>/remote_folder/
</span></span><span style="display:flex;"><span><span style="color:#ef6155">file_id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.ssh/id_ed25519&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>hugo <span style="color:#5bc4bf">&amp;&amp;</span> rsync -avz --delete -e <span style="color:#48b685">&#34;ssh -i </span><span style="color:#f99b15">${</span><span style="color:#ef6155">file_id</span><span style="color:#f99b15">}</span><span style="color:#48b685"> -p </span><span style="color:#f99b15">${</span><span style="color:#ef6155">port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> public/ <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">user</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>@<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">host</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_dist</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><ul>
<li>
<p><code>userid</code> est l&rsquo;identifiant utilisateur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















</p>
</li>
<li>
<p><code>servername</code> est le nom 






















<span lang="en">FQDN <em>(Fully Qualified Domain Name)</em></span>
























































































 ou l&rsquo;adresse 


































<span lang="en">IP <em>(Internet Protocol)</em></span>












































































 du
serveur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 vers lequel se connecter</p>
</li>
<li>
<p><code>remote_folder</code> est le nom réel du répertoire distant sur lequel se connecter.</p>
</li>
</ul>
<p>Cet exemple montre le déploiement d&rsquo;un site avec rsync utilisant une connexion


























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">L&rsquo;exécution de la commande <code>hugo</code> va regénérer chacune des pages. Résultat,
<code>rsync</code> va téléverser à nouveau toutes les pages, et non pas juste celles
modifiées, puisque toutes sont re-générées.</div>


<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Le problème est que si l&rsquo;utilisateur SSH est soumis au chroot</p>
<p><abbr lang="en" title="Secure SHell">SSH</abbr></p>
<p>,
et donc ne peut se connecter qu&rsquo;en</p>
<p><span lang="en">SFTP <em>(SSH File Transfer Protocol)</em></span></p>
<p>, il est impossible
d&rsquo;utiliser <strong>rsync</strong> car il n&rsquo;est pas fait pour communiquer ainsi ;
tout simplement, il ne le peut pas !</p>
<p>C&rsquo;est là, qu&rsquo;entre en jeu, soit :</p>
<ul>
<li>le fait de se connecter en premier avec <a href="/fr/web/hugo/hugo-deploy/#sshfs">SshFS</a></li>
<li>ou d&rsquo;utiliser le très léger client <a href="/fr/web/hugo/hugo-deploy/#lftp">lftp</a>.</li>
<li>voire le puissant logiciel <a href="/fr/web/hugo/hugo-deploy/#rclone">rclone</a>.</li>
</ul>
</div>

<h3 id="sshfs">SshFS</h3>
<p><strong>SshFS</strong> peut être installé par votre gestionnaire de paquets :</p>
<ul>
<li>sous Debian/*Buntu : <code># apt install sshfs</code></li>
<li>sous OpenBSD : <code># pkg_add sshfs</code></li>
</ul>
<p>L&rsquo;avantage de <em>SshFS</em> est que c&rsquo;est un outil qui permet de se connecter
que votre utilisateur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 soit soumis ou non à un chroot


























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 en montant le répertoire distant dans l&rsquo;espace utilisateur
local. <br>
<em>Attention, cela ralentit l&rsquo;accès réseau, rien de grave, mais à savoir…</em></p>
<p>Sous OpenBSD, c&rsquo;est un peu plus délicat ; du fait de fonctionner principalement
sur ce <abbr title="Système d'Exploitation">SE</abbr>
, j&rsquo;expliquerais
pour celui-ci. Au cas où, adaptez à votre cas.
En effet, sous OpenBSD, il est nécessaire d&rsquo;avoir des droits administrateur,
et il est recommandé d&rsquo;avoir paramétré 
<a class="man" href="https://man.openbsd.org/doas" title="Page du Manuel OpenBSD pour : doas">doas</a>
.</p>
<p>Pour monter localement le système de fichier : <br>
<code>:$ doas sshfs -C -p $port -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} &quot;${dir_mount}&quot;</code></p>
<p>Une fois connecté, le répertoire distant est monté localement là où vous
le désirez.</p>
<p>C&rsquo;est le moment d&rsquo;utiliser <code>rsync</code> mais au lieu de chercher à se
connecter - <em>puisque c&rsquo;est déjà fait</em> -, l&rsquo;outil va permettre de synchroniser
d&rsquo;un répertoire source local vers le répertoire source distant, monté localement.</p>
<p><strong>rsync</strong> s&rsquo;utilise donc ainsi : <br>
<code>cd &quot;${dir_local}&quot; &amp;&amp; rsync -av --delete --human-readable --progress --stats  &quot;.&quot; &quot;${dir_mount}&quot;</code></p>
<p>Pour le démonter proprement, ce sera : <br>
<code>:$ doas umount &quot;${dir_mount}&quot;</code></p>
<p>Ceci étant dit, voici à quoi peut ressemble le fichier de déploiement
dans ce contexte SshFS + rsync :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> -n <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$TERM</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> clear
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>userid
</span></span><span style="display:flex;"><span><span style="color:#ef6155">host</span><span style="color:#5bc4bf">=</span>servername
</span></span><span style="display:flex;"><span><span style="color:#ef6155">port</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### the directory where your web site files should go</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## dir_dist: relative to chroot SSH</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_dist</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/www/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_local</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$ROOT</span><span style="color:#48b685">/public/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_mount</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/servers/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">id</span><span style="color:#f99b15">}</span><span style="color:#48b685">/&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">file_id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.ssh/id_ed25519&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">rsync_opts</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;--human-readable --progress --stats &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   Fonctions</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_mount<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">[</span> ! -d <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> mkdir -p <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># for Debian</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">[</span> -d <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> sshfs -C -p <span style="color:#ef6155">$port</span> -o <span style="color:#ef6155">uid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -u <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> -o <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -g <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> -o <span style="color:#ef6155">IdentityFile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file_id</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#f99b15">${</span><span style="color:#ef6155">id</span><span style="color:#f99b15">}</span>@<span style="color:#f99b15">${</span><span style="color:#ef6155">host</span><span style="color:#f99b15">}</span>:<span style="color:#f99b15">${</span><span style="color:#ef6155">dir_dist</span><span style="color:#f99b15">}</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># for OpenBSD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">[</span> -d <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> doas sshfs -C -p <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -o allow_other -o <span style="color:#ef6155">uid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -u <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> -o <span style="color:#ef6155">gid</span><span style="color:#5bc4bf">=</span><span style="color:#815ba4">$(</span>id -g <span style="color:#ef6155">$USER</span><span style="color:#815ba4">)</span> -o <span style="color:#ef6155">IdentityFile</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file_id</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">id</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>@<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">host</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_dist</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_rsync<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    cd <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_local</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">||</span> exit
</span></span><span style="display:flex;"><span>    rsync -av --delete <span style="color:#ef6155">$rsync_opts</span> <span style="color:#48b685">&#34;.&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>_umount<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    fusermount -u <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>    <span style="color:#776e71"># pour Debian</span>
</span></span><span style="display:flex;"><span>    doas umount <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_mount</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#776e71"># pour OpenBSD</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   Execution</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>hugo
</span></span><span style="display:flex;"><span><span style="color:#ef6155">status</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$?</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">status</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -eq <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> _mount; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        _rsync
</span></span><span style="display:flex;"><span>        _umount
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><ul>
<li>
<p><code>userid</code> est l&rsquo;identifiant utilisateur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















</p>
</li>
<li>
<p><code>servername</code> est le nom 























<abbr lang="en" title="Fully Qualified Domain Name">FQDN</abbr>
























































































 ou l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 du
serveur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 vers lequel se connecter</p>
</li>
<li>
<p><code>dir_mount</code> est le nom du répertoire local vers lequel le répertoire
distant va être monté.</p>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION à ne pas utiliser directement ce script, sans mettre en commentaire
les lignes ne correspondant pas à votre OS !</div>

<h3 id="lftp">lftp</h3>
<p><strong>lftp</strong> est un couteau suisse de la connexion réseau. Il fait du 























<span lang="en">FTP <em>(File Transfer Protocol)</em></span>























































































,

























<span lang="en">FTPS <em>(File Transfer Protocol Secure)</em></span>






















































































, de la synchronistation de document, sur 




































<span lang="en">IPv4 <em>(Internet Protocol v4)</em></span>










































































,






































<span lang="en">IPv6 <em>(Internet Protocol v6)</em></span>









































































, au-travers des protocoles HTTP(S) ; il fait même du trafic
bittorent, voire partiellement du WebDAV… et il est capable de se connecter en




















































































<abbr lang="en" title="SSH File Transfer Protocol">SFTP</abbr>




























 !</p>
<p>Voilà le &ldquo;miracle&rdquo; : un client réseau sachant faire du mirroring de données
en 



















































































<abbr lang="en" title="SSH File Transfer Protocol">SFTP</abbr>




























 !!!</p>
<p>Donc, installez avec votre gestionnaire de paquets le binaire :</p>
<ul>
<li>sous Debian/*Buntu : <code>:# apt install lftp</code></li>
<li>sous OpenBSD : <code>:# pkg_add lftp</code></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> -n <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$TERM</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> clear
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>userid
</span></span><span style="display:flex;"><span><span style="color:#ef6155">host</span><span style="color:#5bc4bf">=</span>servername
</span></span><span style="display:flex;"><span><span style="color:#ef6155">port</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### the directory where your web site files should go</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## dir_dist: relative to chroot SSH</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_dist</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/www/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_local</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$ROOT</span><span style="color:#48b685">/public/&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">file_id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.ssh/id_ed25519&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>hugo
</span></span><span style="display:flex;"><span>lftp -e <span style="color:#48b685">&#34;set ftp:ssl-allow no; set sftp:connect-program ssh -a -x -i </span><span style="color:#f99b15">${</span><span style="color:#ef6155">file_id</span><span style="color:#f99b15">}</span><span style="color:#48b685">; mirror -e -R </span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_local</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_dist</span><span style="color:#f99b15">}</span><span style="color:#48b685">; quit;&#34;</span> -p <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">port</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> sftp://<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">id</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">passwd</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>@<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">host</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><ul>
<li>
<p><code>userid</code> est l&rsquo;identifiant utilisateur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















</p>
</li>
<li>
<p><code>servername</code> est le nom 























<abbr lang="en" title="Fully Qualified Domain Name">FQDN</abbr>
























































































 ou l&rsquo;adresse 



































<abbr lang="en" title="Internet Protocol">IP</abbr>












































































 du
serveur 

























































































<abbr lang="en" title="Secure SHell">SSH</abbr>






















 vers lequel se connecter</p>
</li>
</ul>
<h3 id="rclone">rclone</h3>
<p><strong>rclone</strong> est un puissant outil en ligne de commande pour gérer le stockage
de fichiers à-travers de nombreuses solutions de type nuage informatique,
systèmes de fichers divers et variés, mais aussi basiquement par le biais
du protocol 



















































































<abbr lang="en" title="SSH File Transfer Protocol">SFTP</abbr>




























.</p>
<p>Installez avec votre gestionnaire de paquets le binaire :</p>
<ul>
<li>sous Debian/*Buntu : <code>:# apt install rclone</code></li>
<li>sous OpenBSD : <code>:# pkg_add rclone</code></li>
</ul>
<p>La configuration par l&rsquo;usage de l&rsquo;option <code>config</code> tel que : <br>
<code>:$ rclone config</code></p>
<ol>
<li>Nommez votre accès <strong>remote</strong>, tel que vous désirez. Ce nom sera à utiliser
en tant que nom de connexion.</li>
<li>Choisissez absolument la connexion SFTP, en écrivant <code>sftp</code> lorsque l&rsquo;invite
vous pose la question.</li>
</ol>
<p>L&rsquo;invite de commande de rclone est en anglais, mais elle est aisée à utiliser.
<em>Je vous renvoie à la page de la documentation 



















































































<abbr lang="en" title="SSH File Transfer Protocol">SFTP</abbr>




























, dont la
référence est dans la section <a href="/fr/web/hugo/hugo-deploy/#Documentation">Documentation</a> ; allez-y
absolument faire un tour de lecture !</em></p>
<p>Le fichier de configuration se trouvera être écrit dans votre répertoire
personnel <code>~/.config/rclone/rclone.conf</code>, par défaut.</p>
<p>Il sera de ce type :</p>
<pre tabindex="0"><code class="language-conf" data-lang="conf">[nom_remote]
type = sftp
host = adresse_ip ou FQDN
user = id_ssh
port = 22
key_file = ~/.ssh/id_ed25519
key_use_agent = true
pubkey_file = ~/.ssh/id_ed25519.pub
use_insecure_cipher = false
md5sum_command = none
sha1sum_command = none
</code></pre><p>Il ne reste plus qu&rsquo;à utiliser rclone dans votre script de déploiement d&rsquo;Hugo :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> -n <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$TERM</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> clear
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>userid
</span></span><span style="display:flex;"><span><span style="color:#ef6155">host</span><span style="color:#5bc4bf">=</span>servername
</span></span><span style="display:flex;"><span><span style="color:#ef6155">port</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### the directory where your web site files should go</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## dir_dist: relative to chroot SSH</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_dist</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/www/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dir_local</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$ROOT</span><span style="color:#48b685">/public/&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">file_id</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.ssh/id_ed25519&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">rclone_remote</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nom_remote&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>hugo
</span></span><span style="display:flex;"><span>rclone sync -i <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_local</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">rclone_remote</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">dir_dist</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><h2 id="fin">FIN</h2>
<p>Voilà, c&rsquo;est fini.</p>
<p>Maintenant, vous savez déployer votre site statique Hugo, que avec <code>rsync/ssh</code>,
<code>sshfs+rsync</code>, <code>lftp</code>, voire par <code>rclone</code>.</p>
<h2 id="documentation">Documentation</h2>
<p>La documentation officielle :</p>
<ul>
<li><a href="https://gohugo.io/hosting-and-deployment/deployment-with-rsync/#shell-script" title="Lien vers la page du site officiel Hugo : Hosting and deployment &gt; Deployment with rsync">Hugo Documentation : Hosting and deployment &gt; Deployment with rsync</a>
</li>
<li>Le  site web de <a href="https://lftp.yar.ru/" rel="external">lftp</a></li>
<li>La documentation de <a href="https://rclone.org/sftp/" rel="external">rclone:sftp</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Déploiement d&#39;un site, fait avec le générateur Hugo, par rsync&#43;ssh, SFTP avec rsync, le client lftp, voire rclone]]></summary>
        <published>2019-11-29T14:45:12+01:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:57c2c0ee-4257-6c48-b034-6d5e6a89151b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/pysnmp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Pysnmp: outil Python pour SNMP (authPriv v3)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <category term="Python3" scheme="http://doc.huc.fr.eu.org/fr/tags/python3/" />
        <category term="SNMP" scheme="http://doc.huc.fr.eu.org/fr/tags/snmp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>pysnmp</strong> est une librairie en Python, multiplateforme pour
<abbr title="Simple Network Management Protocol">SNMP</abbr>
, capable d&rsquo;agir en
tant qu&rsquo;agent, gestionnaire, proxy, sur les trois versions du protocole
SNMP, de &ldquo;discuter&rdquo; sur les protocoles réseaux IPv(4|6).</p>
<p>Le propos est de <em>(dé)</em> montrer l&rsquo;utilisation de <strong>pysnmp</strong> avec l&rsquo;authentification
forte de la v3 de SNMP.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li>La documentation officielle de la librairie : <a href="http://snmplabs.com/pysnmp/" rel="external">http://snmplabs.com/pysnmp/</a></li>
</ul>
<h2 id="installation">Installation</h2>
<ul>
<li>OpenBSD 6.6</li>
<li>Version : 4.4.6</li>
</ul>
<p>Sous OpenBSD, <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>

le paquet <code>py3-snmp</code></p>
<p>Malheureusement, cette version ne semble pas <em>(pleinement ?)</em> fonctionnelle.</p>
<p>Donc, installons-le par le biais de l&rsquo;outil <code>pip</code> : <br>
<code># python3.7 -m pip install --upgrade --user pysnmp</code></p>
<h3 id="travailler-avec-les-mib-openbsd">Travailler avec les MIB OpenBSD</h3>
<p>L&rsquo;équipe OpenBSD a créé ses propres <abbr title="Management Information Base">MIB</abbr>
 -
<em>ce sont des arborescences de données, que l&rsquo;on peut aussi appeler
&ldquo;base de données arborescente&rdquo;</em> -</p>
<p><strong>pysnmp</strong> nativement n&rsquo;est pas capable de les interroger. Mais heureusement,
on peut lui &ldquo;donner à manger&rdquo;.</p>
<p>Avec <strong>pysnmp</strong> est fourni un outil nommé <code>mibdump.py</code> - <em>depuis la v4.3 ;
avant il fallait utiliser <code>build-pysnmp-mib.py</code></em> -, et lui indiquer le
chemin des MIB d&rsquo;OpenBSD.</p>
<p>Ces MIB sont fournis dans le répertoire <code>/usr/share/snmp/mibs/</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ <span style="color:#815ba4">for</span> file in /usr/share/snmp/mibs/*; <span style="color:#815ba4">do</span> mibdump.py <span style="color:#ef6155">$file</span>; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>Source MIB repositories: /usr/share/snmp/mibs, file:///usr/share/snmp/mibs, http://mibs.snmplabs.com/asn1/@mib@
</span></span><span style="display:flex;"><span>Borrow missing/failed MIBs from: http://mibs.snmplabs.com/pysnmp/notexts/@mib@
</span></span><span style="display:flex;"><span>Existing/compiled MIB locations: pysnmp.smi.mibs, pysnmp_mibs
</span></span><span style="display:flex;"><span>Compiled MIBs destination directory: /home/zou/.pysnmp/mibs
</span></span><span style="display:flex;"><span>MIBs excluded from code generation: INET-ADDRESS-MIB, PYSNMP-USM-MIB, RFC-1212, RFC-1215, RFC1065-SMI, RFC1155-SMI, RFC1158-MIB, RFC1213-MIB, SNMP-FRAMEWORK-MIB, SNMP-TARGET-MIB, SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC, SNMPv2-TM, TRANSPORT-ADDRESS-MIB
</span></span><span style="display:flex;"><span>MIBs to compile: OPENBSD-BASE-MIB
</span></span><span style="display:flex;"><span>Destination format: pysnmp
</span></span><span style="display:flex;"><span>Parser grammar cache directory: not used
</span></span><span style="display:flex;"><span>Also compile all relevant MIBs: yes
</span></span><span style="display:flex;"><span>Rebuild MIBs regardless of age: no
</span></span><span style="display:flex;"><span>Dry run mode: no
</span></span><span style="display:flex;"><span>Create/update MIBs: yes
</span></span><span style="display:flex;"><span>Byte-compile Python modules: yes <span style="color:#5bc4bf">(</span>optimization level no<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Ignore compilation errors: no
</span></span><span style="display:flex;"><span>Generate OID-&gt;MIB index: no
</span></span><span style="display:flex;"><span>Generate texts in MIBs: no
</span></span><span style="display:flex;"><span>Keep original texts layout: no
</span></span><span style="display:flex;"><span>Try various file names <span style="color:#815ba4">while</span> searching <span style="color:#815ba4">for</span> MIB module: yes
</span></span><span style="display:flex;"><span>Created/updated MIBs: OPENBSD-BASE-MIB
</span></span><span style="display:flex;"><span>Pre-compiled MIBs borrowed:
</span></span><span style="display:flex;"><span>Up to date MIBs: OPENBSD-BASE-MIB, SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC
</span></span><span style="display:flex;"><span>Missing source MIBs:
</span></span><span style="display:flex;"><span>Ignored MIBs:
</span></span><span style="display:flex;"><span>Failed MIBs:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p><em>je n&rsquo;ai volontairement recopié que la sortie écran du premier fichier</em></p>
<p>Les lignes à vérifier sont :</p>
<ul>
<li><code>MIBs to compile</code> qui nous montre quel fichier est compilé</li>
<li><code>Created/updated MIBs</code> qui nous restitue le nom du nouveau fichier
compilé</li>
<li><code>Ignored MIBs</code> et <code>Failed MIBs</code> qui peut informer des informations MIB
défectueuses ou ignorées</li>
</ul>
<p>Une fois le traitement terminé, les nouveaux fichiers compilés ont été
créés dans : <code>~/.pysnmp/mibs/</code></p>
<p>Mais avant de (sa?)voir comment utiliser les fichiers MIB nouvellement
créés, voyons comment utiliser <strong>pysnmp</strong> dans le contexte de SNMPv3. <br>
Je m&rsquo;attarderais très particulièrement sur la manière de l&rsquo;utiliser avec
l&rsquo;authentification forte.</p>
<h2 id="coding">Coding</h2>
<p>Appelons l&rsquo;outil :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> PrettyPrinter
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pysnmp.hlapi</span> <span style="color:#5bc4bf">import</span> <span style="color:#5bc4bf">*</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pysnmp.smi.view</span> <span style="color:#5bc4bf">import</span> MibViewController
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pp <span style="color:#5bc4bf">=</span> PrettyPrinter(indent<span style="color:#5bc4bf">=</span><span style="color:#f99b15">4</span>)
</span></span></code></pre></div><p>Puis paramétrons les variables nécessaires pour l&rsquo;authentification forte, à savoir :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span>host <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;localhost&#34;</span>
</span></span><span style="display:flex;"><span>user <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;uenc&#34;</span>
</span></span><span style="display:flex;"><span>authkey <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;zx4pyrfyeu5x5c3kxqirhtsxksbmawju&#34;</span>
</span></span><span style="display:flex;"><span>privkey <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz&#34;</span>
</span></span></code></pre></div><p><em>j&rsquo;ai repris celles de l&rsquo;exemple, dans l&rsquo;article sur l&rsquo;outil natif à OpenBSD,
<a class="inside" href="/fr/sys/openbsd/snmp/#authentification-forte" title="Lien interne vers l&#39;article : 'snmp : client SNMP sous OpenBSD'">snmp</a>
,
ni plus ni moins.</em></p>
<h3 id="snmp-engine-mib-view-controller">SNMP Engine, MIB View Controller</h3>
<p>Une des premières choses à déclarer est le <strong>Contrôleur de Vue MIB</strong>, qui
nécessite la création d&rsquo;un <strong>moteur SNMP</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#776e71"># create SNMP Engine and MIB view Controller</span>
</span></span><span style="display:flex;"><span>se <span style="color:#5bc4bf">=</span> SnmpEngine()
</span></span><span style="display:flex;"><span>mvc <span style="color:#5bc4bf">=</span> se<span style="color:#5bc4bf">.</span>getUserContext(<span style="color:#48b685">&#39;mibViewController&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">not</span> mvc:
</span></span><span style="display:flex;"><span>   mvc <span style="color:#5bc4bf">=</span> MibViewController(se<span style="color:#5bc4bf">.</span>getMibBuilder())
</span></span></code></pre></div><p>Et, maintenant, nous allons voir comment appeler les MIB d&rsquo;OpenBSD !</p>
<h3 id="oid--mib">OID + MIB</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#776e71"># get Object Identity and Type</span>
</span></span><span style="display:flex;"><span>oi <span style="color:#5bc4bf">=</span> ObjectIdentity(<span style="color:#48b685">&#39;iso.org.dod.internet.private.enterprises.openBSD.memMIBObjects&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>addMibSource(<span style="color:#48b685">&#39;~/.pysnmp/mibs/&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-BASE-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-CARP-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-MEM-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-PF-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-RELAYD-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-SENSORS-MIB&#39;</span>)
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>loadMibs(<span style="color:#48b685">&#39;OPENBSD-SNMPD-CONF&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>oi<span style="color:#5bc4bf">.</span>resolveWithMib(mvc)
</span></span></code></pre></div><ul>
<li><code>ObjectIdenttity()</code> : en premier, nous construisons un objet identifiant,
selon un OID précis que nous recherchons - <em>ici le nombre d&rsquo;interfaces
vues par la MIB PF d&rsquo;OpenBSD</em></li>
<li><code>addMibSource()</code> : référence le chemin où ont été créé les fichiers MIB
précédemment</li>
<li><code>loadMibs()</code> : pour appeler chacun des fichiers MIB créés précédemment
<ul>
<li><em>pour info, selon l&rsquo;OID recherché, il n&rsquo;est pas forcément nécessaire
de toutes les charger</em> -</li>
</ul>
</li>
<li><code>resolvedWithMib()</code> : nous permet d&rsquo;appliquer le Contrôleur de Vue MIB
sur l&rsquo;objet</li>
</ul>
<p>Continuons avec la gestion des données utilisateurs  nécessaires à
l&rsquo;identification :</p>
<h3 id="usm-user-data">USM User Data</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span>uud <span style="color:#5bc4bf">=</span> UsmUserData(user, authKey<span style="color:#5bc4bf">=</span>authkey, privKey<span style="color:#5bc4bf">=</span>privkey,
</span></span><span style="display:flex;"><span>            authProtocol<span style="color:#5bc4bf">=</span>usmHMAC384SHA512AuthProtocol,
</span></span><span style="display:flex;"><span>            privProtocol<span style="color:#5bc4bf">=</span>usmAesCfb128Protocol)
</span></span></code></pre></div><p>Pour information, les différentes valeurs du protocole de chiffrement
d&rsquo;authentification sont :</p>
<ul>
<li><code>usmNoAuthProtocol</code> pour aucun protocol</li>
<li><code>usmHMACMD5AuthProtocol</code> pour le chiffrement <code>MD5</code></li>
<li><code>usmHMACSHAAuthProtocol</code> pour <code>SHA</code></li>
<li><code>usmHMAC128SHA224AuthProtocol</code> pour <code>SHA-224</code></li>
<li><code>usmHMAC192SHA256AuthProtocol</code> pour <code>SHA-256</code></li>
<li><code>usmHMAC256SHA384AuthProtocol</code> pour <code>SHA-384</code></li>
<li><code>usmHMAC384SHA512AuthProtocol</code> pour <code>SHA-512</code></li>
</ul>
<p>Concernant le chiffrement du protocole de confidentialité, ces valeurs
sont :</p>
<ul>
<li><code>usmNoPrivProtocol</code> si aucun</li>
<li><code>usmDESPrivProtocol</code> pour <code>DES</code></li>
<li><code>usmAesCfb128Protocol</code> pour <code>AES</code></li>
</ul>
<p><em>(Pour information, il en existe d&rsquo;autres, mais ce sont surtout des &ldquo;drafts&rdquo;,
du moins pour l&rsquo;instant !)</em></p>
<h3 id="générateur">Générateur</h3>
<p>Nous avons besoin de construire le générateur de la commande <code>get</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span>gc <span style="color:#5bc4bf">=</span> getCmd(se, uud, UdpTransportTarget((host, <span style="color:#f99b15">161</span>)), ContextData(),
</span></span><span style="display:flex;"><span>    ObjectType(oi))
</span></span></code></pre></div><h3 id="retourner-le-résultat">Retourner le résultat</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#776e71"># return results</span>
</span></span><span style="display:flex;"><span>errorIndication, errorStatus, errorIndex, varBinds <span style="color:#5bc4bf">=</span> next(gc)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Display informations</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> errorIndication:
</span></span><span style="display:flex;"><span>    print(str(errorIndication))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">elif</span> errorStatus:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">%s</span><span style="color:#48b685"> at </span><span style="color:#f99b15">%s</span><span style="color:#48b685">&#39;</span> <span style="color:#5bc4bf">%</span> (str(errorStatus<span style="color:#5bc4bf">.</span>prettyPrint()),
</span></span><span style="display:flex;"><span>        errorIndex <span style="color:#5bc4bf">and</span> varBinds[int(errorIndex) <span style="color:#5bc4bf">-</span> <span style="color:#f99b15">1</span>][<span style="color:#f99b15">0</span>] <span style="color:#5bc4bf">or</span> <span style="color:#48b685">&#39;?&#39;</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> varBind <span style="color:#5bc4bf">in</span> varBinds:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        oid <span style="color:#5bc4bf">=</span> varBind[<span style="color:#f99b15">0</span>]
</span></span><span style="display:flex;"><span>        value <span style="color:#5bc4bf">=</span> varBind[<span style="color:#f99b15">1</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        print(oid)
</span></span><span style="display:flex;"><span>        print(value)
</span></span></code></pre></div><p><em>ne pas s&rsquo;inquiéter du temps que mets la requête à s&rsquo;afficher ; cela est
dû au chiffrement des informations</em></p>
<p>L&rsquo;exécution nous retourne ceci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#f99b15">1.3.6.1.4.1.30155.5</span>
</span></span></code></pre></div><h3 id="fin">Fin</h3>
<p>Pour finir, nous venons de voir que discuter avec l&rsquo;outil <strong>pysnmp</strong> sur
SNMPv3 avec authentification forte <strong>EST</strong> possible.</p>
<p>Le plus délicat est de récupérer les informations dans les MIB. Trés vite,
vous allez avoir à buter sur des erreurs incompréhensibles, et difficiles
à résoudre. <br>
Et, ça, ça le don de m&rsquo;énerver ! <em>(enfin presque…)</em></p>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>J&rsquo;ai beaucoup appris grâce à cet <a href="https://makina-corpus.com/blog/metier/2016/initiation-a-snmp-avec-python-pysnmp-partie2" rel="external">article</a>, trouvé sur le site <strong>Makina Corpus</strong>.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[pysnmp : outil Python pour SNMP ; utilisation sous OpenBSD, principalement v3 avec authentification forte]]></summary>
        <published>2019-11-27T22:50:53+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:caee0147-df0c-d52e-8dc0-8cb99155edcd</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nextcloud/occ/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nextcloud : manpage occ</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <category term="occ" scheme="http://doc.huc.fr.eu.org/fr/tags/occ/" />
        <content type="html"><![CDATA[<h2 id="occ">occ</h2>
<p>Usage:
<code>command [options] [arguments]</code></p>
<p>Options:</p>
<ul>
<li><code>-h</code>, <code>--help</code>            Display this help message</li>
<li><code>-q</code>, <code>--quiet</code>           Do not output any message</li>
<li><code>-V</code>, <code>--version</code>         Display this application version
<ul>
<li><code>--ansi</code>              Force ANSI output</li>
<li><code>--no-ansi</code>           Disable ANSI output</li>
</ul>
</li>
<li><code>-n</code>, <code>--no-interaction</code>  Do not ask any interactive question
<ul>
<li><code>--no-warnings</code>       Skip global warnings, show command output only</li>
</ul>
</li>
<li><code>-v</code>|<code>vv</code>|<code>vvv</code>, <code>--verbose</code>  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</li>
</ul>
<p>Available commands:</p>
<ul>
<li><code>check</code>                   check dependencies of the server environment</li>
<li><code>help</code>                    displays help for a command</li>
<li><code>list</code>                    Lists commands</li>
<li><code>status</code>                  show some status information</li>
<li><code>upgrade</code>                 run upgrade routines after installation of a new release. The release has to be installed before.</li>
</ul>
<h3 id="manage-configuration">Manage configuration</h3>
<p><code>config</code></p>
<ul>
<li><code>config:app:delete</code>                   Delete an app config value</li>
<li><code>config:app:get</code>                      Get an app config value</li>
<li><code>config:app:set</code>                      Set an app config value</li>
<li><code>config:import</code>                       Import a list of configs</li>
<li><code>config:list</code>                         List all configs</li>
<li><code>config:system:delete</code>                Delete a system config value</li>
<li><code>config:system:get</code>                   Get a system config value</li>
<li><code>config:system:set</code>                   Set a system config value</li>
</ul>
<h3 id="manage-database">Manage Database</h3>
<p><code>db</code></p>
<ul>
<li><code>db:add-missing-indices</code>              Add missing indices to the database tables</li>
<li><code>db:convert-filecache-bigint</code>         Convert the ID columns of the filecache to BigInt</li>
<li><code>db:convert-mysql-charset</code>            Convert charset of MySQL/MariaDB to use utf8mb4</li>
<li><code>db:convert-type</code>                     Convert the Nextcloud database to the newly configured one</li>
</ul>
<h3 id="encryption-management">Encryption Management</h3>
<p><code>encryption</code></p>
<ul>
<li><code>encryption:change-key-storage-root</code>  Change key storage root</li>
<li><code>encryption:decrypt-all</code>              Disable server-side encryption and decrypt all files</li>
<li><code>encryption:disable</code>                  Disable encryption</li>
<li><code>encryption:enable</code>                   Enable encryption</li>
<li><code>encryption:encrypt-all</code>              Encrypt all files for all users</li>
<li><code>encryption:list-modules</code>             List all available encryption modules</li>
<li><code>encryption:set-default-module</code>       Set the encryption default module</li>
<li><code>encryption:show-key-storage-root</code>    Show current key storage root</li>
<li><code>encryption:status</code>                   Lists the current status of encryption</li>
</ul>
<h3 id="federation-management">Federation Management</h3>
<p><code>federation</code></p>
<ul>
<li><code>federation:sync-addressbooks</code>        Synchronizes addressbooks of all federated clouds</li>
</ul>
<h3 id="files-management">Files Management</h3>
<p><code>files</code></p>
<ul>
<li><code>files:cleanup</code>                       cleanup filecache</li>
<li><code>files:recommendations:recommend</code></li>
<li><code>files:scan</code>                         rescan filesystem</li>
<li><code>files:scan-app-data</code>                rescan the AppData folder</li>
<li><code>files:transfer-ownership</code>           All files and folders are moved to another user - shares are moved as well.</li>
</ul>
<h3 id="groups-management">Groups Management</h3>
<p><code>group</code></p>
<ul>
<li><code>group:add</code>                           Add a group</li>
<li><code>group:adduser</code>                       add a user to a group</li>
<li><code>group:delete</code>                        Remove a group</li>
<li><code>group:list</code>                          list configured groups</li>
<li><code>group:removeuser</code>                    remove a user from a group</li>
</ul>
<h3 id="integrity-app-core">Integrity App, Core</h3>
<p><code>integrity</code></p>
<ul>
<li><code>integrity:check-app</code>                 Check integrity of an app using a signature.</li>
<li><code>integrity:check-core</code>                Check integrity of core code using a signature.</li>
<li><code>integrity:sign-app</code>                  Signs an app using a private key.</li>
<li><code>integrity:sign-core</code>                 Sign core using a private key.</li>
</ul>
<h3 id="logs-management">Logs Management</h3>
<p><code>log</code></p>
<ul>
<li><code>log:file</code>                           manipulate logging backend</li>
<li><code>log:manage</code>                          manage logging configuration</li>
<li><code>log:tail</code>                            Tail the nextcloud logfile</li>
<li><code>log:watch</code>                           Watch the nextcloud logfile</li>
</ul>
<h3 id="nc-background-jobs">NC Background jobs</h3>
<p><code>background</code></p>
<ul>
<li><code>background:ajax</code>                     Use ajax to run background jobs</li>
<li><code>background:cron</code>                     Use cron to run background jobs</li>
<li><code>background:webcron</code>                  Use webcron to run background jobs</li>
</ul>
<h3 id="nc-maintenance">NC Maintenance</h3>
<p><code>maintenance</code></p>
<ul>
<li><code>maintenance:data-fingerprint</code>        update the systems data-fingerprint after a backup is restored</li>
<li><code>maintenance:mimetype:update-db</code>      Update database mimetypes and update filecache</li>
<li><code>maintenance:mimetype:update-js</code>      Update mimetypelist.js</li>
<li><code>maintenance:mode</code>                    set maintenance mode</li>
<li><code>maintenance:repair</code>                  repair this installation</li>
<li><code>maintenance:theme:update</code>            Apply custom theme changes</li>
<li><code>maintenance:update:htaccess</code>         Updates the .htaccess file</li>
</ul>
<h3 id="nc-migration">NC Migration</h3>
<p><code>migrations</code></p>
<ul>
<li><code>migrations:execute</code>                  Execute a single migration version manually.</li>
<li><code>migrations:generate</code></li>
<li><code>migrations:generate-from-schema</code></li>
<li><code>migrations:migrate</code>                  Execute a migration to a specified version or the latest available version.</li>
<li><code>migrations:status</code>                   View the status of a set of migrations.</li>
</ul>
<h3 id="nc-security">NC Security</h3>
<p><code>security</code></p>
<ul>
<li><code>security:certificates</code>               list trusted certificates</li>
<li><code>security:certificates:import</code>        import trusted certificate</li>
<li><code>security:certificates:remove</code>        remove trusted certificate</li>
</ul>
<h3 id="nc-update">NC Update</h3>
<p><code>update</code></p>
<ul>
<li><code>update:check</code>                        Check for server and app updates</li>
</ul>
<h3 id="user-management">User management</h3>
<p><code>user</code></p>
<ul>
<li><code>user:add</code>                            adds a user</li>
<li><code>user:delete</code>                         deletes the specified user and all datas user</li>
<li><code>user:disable</code>                        disables the specified user</li>
<li><code>user:enable</code>                         enables the specified user</li>
<li><code>user:info</code>                           show user info</li>
<li><code>user:lastseen</code>                       shows when the user was logged in last time</li>
<li><code>user:list</code>                           list configured users</li>
<li><code>user:report</code>                         shows how many users have access</li>
<li><code>user:resetpassword</code>                  Resets the password of the named user</li>
<li><code>user:setting</code>                        Read and modify user settings</li>
</ul>
<p><code>notification</code></p>
<ul>
<li><code>notification:generate</code>               Generate a notification for the given user</li>
</ul>
<p><code>versions</code></p>
<ul>
<li><code>versions:cleanup</code>                    Delete versions: delete versions of the given user(s), if no user is given all versions will be deleted</li>
<li><code>versions:expire</code>                     Expires the users file versions: expire file versions of the given user(s), if no user is given file versions for all users will be expired.</li>
</ul>
<h3 id="manage-applications">Manage applications</h3>
<p><code>app</code></p>
<ul>
<li><code>app:check-code</code>                      check code to be compliant</li>
<li><code>app:disable</code>                         disable an app</li>
<li><code>app:enable</code>                          enable an app</li>
<li><code>app:getpath</code>                         Get an absolute path to the app directory</li>
<li><code>app:install</code>                         install an app</li>
<li><code>app:list</code>                            List all available apps</li>
<li><code>app:remove</code>                          remove an app</li>
<li><code>app:update</code>                          update an app or all apps</li>
</ul>
<h4 id="mail">Mail</h4>
<p><code>mail</code></p>
<ul>
<li><code>mail:account:create</code>                 creates IMAP account</li>
<li><code>mail:account:export</code>                 Exports a user&rsquo;s IMAP account(s)</li>
</ul>
<h4 id="circles">Circles</h4>
<p><code>circles</code></p>
<ul>
<li><code>circles:clean</code>                       remove all extra data from database</li>
<li><code>circles:fixuniqueid</code>                 fix Unique Id issue.</li>
</ul>
<h4 id="deck">Deck</h4>
<p><code>deck</code></p>
<ul>
<li><code>deck:export</code>                         Export a JSON dump of user data</li>
</ul>
<h4 id="talk">Talk</h4>
<p><code>talk</code></p>
<ul>
<li><code>talk:command:add</code>                    Add a new command</li>
<li><code>talk:command:add-samples</code>            Adds some sample commands: /wiki, …</li>
<li><code>talk:command:delete</code>                 Remove an existing command</li>
<li><code>talk:command:list</code>                   List all available commands</li>
<li><code>talk:command:update</code>                 Add a new command</li>
<li><code>talk:signaling:add</code>                  Add an external signaling server.</li>
<li><code>talk:signaling:delete</code>               Remove an existing signaling server.</li>
<li><code>talk:signaling:list</code>                 List external signaling servers.</li>
<li><code>talk:stun:add</code>                       Add a new STUN server.</li>
<li><code>talk:stun:delete</code>                    Remove an existing STUN server.</li>
<li><code>talk:stun:list</code>                      List STUN servers.</li>
<li><code>talk:turn:add</code>                       Add a TURN server.</li>
<li><code>talk:turn:delete</code>                    Remove an existing TURN server.</li>
<li><code>talk:turn:list</code>                      List TURN servers.</li>
</ul>
<h4 id="2fa-two-factor-auth">2FA: Two Factor Auth</h4>
<p><code>twofactorauth</code></p>
<ul>
<li><code>twofactorauth:cleanup</code>               Clean up the two-factor user-provider association of an uninstalled/removed provider</li>
<li><code>twofactorauth:disable</code>               Disable two-factor authentication for a user</li>
<li><code>twofactorauth:enable</code>                Enable two-factor authentication for a user</li>
<li><code>twofactorauth:enforce</code>               Enabled/disable enforced two-factor authentication</li>
<li><code>twofactorauth:state</code>                 Get the two-factor authentication (2FA) state of a user</li>
</ul>
<h4 id="webdav">WebDAV</h4>
<p><code>dav</code></p>
<ul>
<li><code>dav:create-addressbook</code>              Create a dav addressbook</li>
<li><code>dav:create-calendar</code>                 Create a dav calendar</li>
<li><code>dav:list-calendars</code>                  List all calendars of a user</li>
<li><code>dav:move-calendar</code>                   Move a calendar from an user to another</li>
<li><code>dav:remove-invalid-shares</code>           Remove invalid dav shares</li>
<li><code>dav:send-event-reminders</code>            Sends event reminders</li>
<li><code>dav:sync-birthday-calendar</code>          Synchronizes the birthday calendar</li>
<li><code>dav:sync-system-addressbook</code>         Synchronizes users to the system addressbook</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Manpage of occ commander into Nextcloud]]></summary>
        <published>2019-11-23T21:59:23+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:694426c5-77f5-7e28-fa56-67ac0ec0cd87</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nextcloud/nextcloud-upgrade/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nextcloud: Mise à jour manuelle sur OpenBSD (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="upgrade" scheme="http://doc.huc.fr.eu.org/fr/tags/upgrade/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Mettre à jour <abbr title="Nextcloud">NC</abbr>
 <em>(Nextcloud)</em> n&rsquo;est pas compliqué en soit…
Soit, vous le faites :</p>
<ul>
<li>Par le biais de l&rsquo;interface web d&rsquo;administration.</li>
<li>Manuellement</li>
<li>Par le gestionnaire de paquets, s&rsquo;il y a lieu.</li>
</ul>
<p>Cet article a juste pour propos d&rsquo;expliquer succinctement le processus manuel
sous OpenBSD. L&rsquo;instance que j&rsquo;administre est donc sous OpenBSD, desservie par
le serveur web Nginx, et le couple PHP+MySQL <em>(en l&rsquo;occurence actuellement PHP 7.3)</em></p>
<h2 id="processus-de-mise-à-jour">Processus de mise à jour</h2>
<p>C&rsquo;est le processus que j&rsquo;utilise depuis plusieurs années, depuis la version 15.*,
qui en fait se veut simple, pratique et rapide.</p>
<h3 id="arrêt-du-service-web">Arrêt du service web</h3>
<p>La première chose que je fais est de désactiver le domaine au niveau de nginx :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rm -f /etc/nginx/sites-enabled/mon-domaine.net
</span></span><span style="display:flex;"><span>:# nginx -t <span style="color:#5bc4bf">&amp;&amp;</span> rcctl restart nginx
</span></span></code></pre></div><h3 id="préparations">Préparations</h3>
<p>Partons du principe que l&rsquo;utilisateur web est <code>www</code>.</p>
<p>Les actions qui suivent sont à faire avec ces droits : <code>$ su -l www</code></p>
<ol>
<li>Direction vers le répertoire de nextcloud : <br>
<code>cd www/nextcloud</code></li>
<li>Il <a class="inside" href="/fr/web/nextcloud/nextcloud-php-chroot/" title="Lien interne vers l&#39;article : 'Nextcloud Php Chroot OpenBSD (astuce)'">faut légérement modifier</a>

le fichier de config : <br>
<code>sed -i -e 's#/htdocs#/var/www/htdocs#' config/config.php</code></li>
<li>Activation du mode de maintenance: <br>
<code>php-7.3 occ maintenance:mode --on</code></li>
</ol>
<h4 id="téléchargement">Téléchargement</h4>
<p>Astuce d&rsquo;informaticien :</p>
<ol>
<li>Direction le répertoire parent <code>www\</code> :</li>
<li>Création d&rsquo;une variable de version <code>v</code> qui sera bien utile.</li>
<li>Téléchargement de l&rsquo;archive actuelle correspondante à la version, ainsi que
du fichier de sommes de contrôle sha256, fournis par le projet NC.</li>
<li>Vérification de la somme de contrôle</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ cd ../
</span></span><span style="display:flex;"><span>:$ <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;17.0.1&#34;</span>
</span></span><span style="display:flex;"><span>:$ <span style="color:#815ba4">for</span> ext in bz2 bz2.sha256; <span style="color:#815ba4">do</span> curl -O https://download.nextcloud.com/server/releases/nextcloud-<span style="color:#ef6155">$v</span>.tar.<span style="color:#ef6155">$ext</span>; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>:$ sha256 -c nextcloud-<span style="color:#ef6155">$v</span>.tar.bz2.sha256
</span></span></code></pre></div><p>Si par exemple, le résultat du SHA est <code>(SHA256) nextcloud-$v.tar.bz2: OK</code>,
c&rsquo;est tout bon.</p>
<h4 id="installation">Installation</h4>
<p>Passons à la phse d&rsquo;installation :</p>
<ul>
<li>déplace l&rsquo;actuel répertoire <code>nextcloud</code> en le renommant suivi de la date de
transformation et du numéro de l&rsquo;ancienne version</li>
<li>décompression de l&rsquo;archive,</li>
<li>suppression d&rsquo;un fichier <em>(on ne cherche pas à installer, ni à ré-installer NC)</em>.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ <span style="color:#ef6155">oldvers</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;16.0.6&#34;</span>
</span></span><span style="display:flex;"><span>:$ <span style="color:#ef6155">date</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>date <span style="color:#48b685">&#39;+%Y%m%d%H%M%S&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>:$ <span style="color:#ef6155">oldnc</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nextcloud-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">date</span><span style="color:#f99b15">}</span><span style="color:#48b685">-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">oldvers</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>:$ mv nextcloud <span style="color:#f99b15">${</span><span style="color:#ef6155">oldnc</span><span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ tar xjvf nextcloud-<span style="color:#ef6155">$v</span>.tar.bz2
</span></span><span style="display:flex;"><span>:$ rm -fP config/CAN_INSTALL
</span></span></code></pre></div><h4 id="vérifications-primaires">Vérifications primaires</h4>
<p>Là, il faut être un peu plus attentif :</p>
<ul>
<li>Copie l&rsquo;ancien fichier de configuration vers le nouveau répertoire de
configuration : <br>
<code>cp ${oldnc}/config/config.php nextcloud/config/</code></li>
<li>Maintenant, il faut parcourir l&rsquo;ancien répertoire des applications pour copier
celles qui <strong>ne sont pas natives</strong> vers le nouveau répertoire d&rsquo;applications.
<strong>Ne recopiez pas telle qu&rsquo;elle la commande qui suit, c&rsquo;est juste pour mémo</strong> : <br>
<code>cp all ${oldnc}/apps diff to new nextcloud-app</code></li>
<li>Pour finir, si besoin, il faut faire de même avec le répertoire des thèmes.</li>
</ul>
<h4 id="permissions">Permissions</h4>
<ul>
<li>Attribution des droits utilisateurs sur tous les nouveaux fichiers et
répertoires dans le répertoire <code>nextcloud/</code>.</li>
<li>Puis, attribution des droits nécessaires d&rsquo;abord sur tous les répertoires
enfants, ensuite ceux pour les fichiers enfants.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ <span style="color:#ef6155">webuser</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;www&#34;</span>
</span></span><span style="display:flex;"><span>:$ chown -R <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">webuser</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:www nextcloud
</span></span><span style="display:flex;"><span>:$ find nextcloud/ -type d -exec chmod <span style="color:#f99b15">750</span> <span style="color:#5bc4bf">{}</span> <span style="color:#f99b15">\;</span>
</span></span><span style="display:flex;"><span>:$ find nextcloud/ -type f -exec chmod <span style="color:#f99b15">640</span> <span style="color:#5bc4bf">{}</span> <span style="color:#f99b15">\;</span>
</span></span></code></pre></div><h3 id="mise-à-jour">Mise à jour</h3>
<ul>
<li>La mise à jour de NC en soit ; rien de particulier, pour autant qu&rsquo;on soit
dans le bon répertoire : <br>
<code>cd nextcloud/</code></li>
<li>Ensuite, utilisation de l&rsquo;outil <code>occ</code> : <br>
<code>php-7.3 occ upgrade</code>
<ul>
<li>Si cela finit avec le message de succès, sortie du mode maintenance : <br>
<code>php-7.3 occ maintenance:mode --off</code></li>
</ul>
</li>
</ul>
<p>Pour finir, ré-édition du fichier de configuration pour supprimer <code>/var/www</code> : <br>
<code>sed -i -e 's#/var/www/htdocs#/htdocs#' config/config.php</code></p>
<h3 id="rédemarrage-service-web">Rédemarrage Service Web</h3>
<ul>
<li>Ré-active le domaine et redémarrage du service web :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# cd /etc/nginx/sites-available/
</span></span><span style="display:flex;"><span>:# ln -s mon-domaine.net ../sites-enabled/
</span></span><span style="display:flex;"><span>:# nginx -t <span style="color:#5bc4bf">&amp;&amp;</span> rcctl restart nginx
</span></span></code></pre></div><ul>
<li>Puis connexion à l&rsquo;interface web d&rsquo;administration en tant qu&rsquo;administrateur,
et mise à jour des différentes applications</li>
</ul>
<p>Et, voilà !</p>
<h3 id="tldr">TL;DR</h3>
<span class="error">
Attention si vous ne faites que recopier tel quel ce TL;DR, vous allez au casse-pipe !
</span>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>// stop web services
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rm -f /etc/nginx/sites-enabled/mon-domaine.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># nginx -t &amp;&amp; rcctl restart nginx</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// connexion as user web
</span></span><span style="display:flex;"><span><span style="color:#776e71"># webuser=&#34;www&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># su -l $webuser</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ cd /var/www/htdocs/mon-domaine.net/www/nextcloud/
</span></span><span style="display:flex;"><span>$ sed -i -e <span style="color:#48b685">&#39;s#/htdocs#/var/www/htdocs#&#39;</span> config/config.php
</span></span><span style="display:flex;"><span>$ php-7.3 occ maintenance:mode --on
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// downlad archives, and checksum
</span></span><span style="display:flex;"><span>$ cd ../
</span></span><span style="display:flex;"><span>$ <span style="color:#ef6155">v</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;17.0.1&#34;</span>
</span></span><span style="display:flex;"><span>$ <span style="color:#815ba4">for</span> ext in bz2 bz2.sha256; <span style="color:#815ba4">do</span> curl -O https://download.nextcloud.com/server/releases/nextcloud-<span style="color:#ef6155">$v</span>.tar.<span style="color:#ef6155">$ext</span>; <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>$ sha256 -c nextcloud-<span style="color:#ef6155">$v</span>.tar.bz2.sha256
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// Untar
</span></span><span style="display:flex;"><span>$ <span style="color:#ef6155">oldvers</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;16.0.6&#34;</span>
</span></span><span style="display:flex;"><span>$ <span style="color:#ef6155">date</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>date <span style="color:#48b685">&#39;+%Y%m%d%H%M%S&#39;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>$ <span style="color:#ef6155">oldnc</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;nextcloud-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">date</span><span style="color:#f99b15">}</span><span style="color:#48b685">-</span><span style="color:#f99b15">${</span><span style="color:#ef6155">oldvers</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>$ mv nextcloud <span style="color:#f99b15">${</span><span style="color:#ef6155">oldnc</span><span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ tar xjvf nextcloud-<span style="color:#ef6155">$v</span>.tar.bz2
</span></span><span style="display:flex;"><span>$ rm -fP config/CAN_INSTALL
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// cp config
</span></span><span style="display:flex;"><span>$ cp <span style="color:#f99b15">${</span><span style="color:#ef6155">oldnc</span><span style="color:#f99b15">}</span>/config/config.php nextcloud/config/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// cp only apps not native; dont recopy this command as-is:
</span></span><span style="display:flex;"><span>$ cp all <span style="color:#f99b15">${</span><span style="color:#ef6155">oldnc</span><span style="color:#f99b15">}</span>/apps diff to new nextcloud/apps
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// egual <span style="color:#815ba4">for</span> themes, <span style="color:#815ba4">if</span> need
</span></span><span style="display:flex;"><span>$ cp all <span style="color:#f99b15">${</span><span style="color:#ef6155">oldnc</span><span style="color:#f99b15">}</span>/themes to new nextcloud/themes
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ chown -R <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">webuser</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>:www nextcloud
</span></span><span style="display:flex;"><span>$ find nextcloud/ -type d -exec chmod <span style="color:#f99b15">750</span> <span style="color:#5bc4bf">{}</span> <span style="color:#f99b15">\;</span>
</span></span><span style="display:flex;"><span>$ find nextcloud/ -type f -exec chmod <span style="color:#f99b15">640</span> <span style="color:#5bc4bf">{}</span> <span style="color:#f99b15">\;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// occ upgrage process
</span></span><span style="display:flex;"><span>$ cd nextcloud/
</span></span><span style="display:flex;"><span>$ php-7.3 occ upgrade
</span></span><span style="display:flex;"><span>$ php-7.3 occ maintenance:mode --off
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ sed -i -e <span style="color:#48b685">&#39;s#/var/www/htdocs#/htdocs#&#39;</span> config/config.php
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// exit
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>// restart web services
</span></span><span style="display:flex;"><span><span style="color:#776e71"># cd /etc/nginx/sites-available/</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ln -s mon-domaine.net ../sites-enabled/</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># nginx -t &amp;&amp; rcctl restart nginx</span>
</span></span></code></pre></div><h3 id="dépannages">Dépannages</h3>
<p>Si la mise à jour échoue, avec l&rsquo;un de ces messages d&rsquo;erreurs :</p>
<h4 id="erreur--nextcloud-is-not-installed">Erreur : Nextcloud is not installed</h4>
<p>Tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ php-7.3 occ help upgrade
</span></span><span style="display:flex;"><span>Nextcloud is not installed - only a limited number of commands are available
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  Command <span style="color:#48b685">&#34;upgrade&#34;</span> is not defined.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>help <span style="color:#5bc4bf">[</span>--format FORMAT<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>--raw<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>--<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;command_name&gt;<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><p>Première chose à s&rsquo;assurer est de vérifier que vous avez bien recopié l&rsquo;ancien
fichier de configuration vers le nouveau répertoire de configuration.</p>
<p>Si oui, et que le problème perdure, essayez : <br>
<code>php-7.3 occ maintenance:repair</code></p>
<h4 id="erreur-vous-essayez-de-réinstaller-votre-nextcloud">Erreur: vous essayez de réinstaller votre Nextcloud</h4>
<p>Lorsque vous vous connectez à l&rsquo;interface web, vous avez le message suivant :</p>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            <p class="IMP text-dark">Erreur</p>
<p>On dirait que vous essayez de réinstaller votre Nextcloud. Toutefois, le fichier CAN_INSTALL est absent de votre répertoire de configuration. Veuillez créer le fichier CAN_INSTALL dans votre dossier de configuration pour continuer</p>
        </blockquote>
    </figure>
</div>

<p>Allez supprimer le fichier <code>CAN_INSTALL</code> qui se trouve dans le nouveau
répertoire de configuration</p>
<h4 id="les-fichiers-ne-sont-plus-visibles">Les fichiers ne sont plus visibles</h4>
<p>Essayez : <code>php-7.3 console.php files:scan --all</code></p>
<hr>
<h2 id="commandes-occ">Commandes OCC</h2>
<p>Pour rappel, les différentes commandes occ, bien utiles : <code>php occ list</code></p>
<p>Retrouvez une liste d&rsquo;informations bien pratique sur la page
<a class="inside" href="/fr/web/nextcloud/occ/" title="Lien interne vers l&#39;article : 'Nextcloud : manpage occ'">occ</a>
.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre à jour Nextcloud manuellement sous OpenBSD]]></summary>
        <published>2019-11-23T20:45:23+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2095748a-8df6-da26-79aa-0b929c374280</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/openbsd-munin-node/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Munin-node : Client pour monitorer OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Munin" scheme="http://doc.huc.fr.eu.org/fr/tags/munin/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="client" scheme="http://doc.huc.fr.eu.org/fr/tags/client/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong>Munin</strong> est un outil de surveillance des ordinateurs. Il présente ces
informations par le biais d&rsquo;une interface web, qui visualise des graphiques
statiques, générés toutes les 5 minutes, par défaut. Un certain nombre de
plugins de monitoring divers sont utilisables sans gros effort.</p>
<p><strong>Munin</strong> permet de monitorer facilement la performance de tout matériel
informatique (ordinateurs, réseaux, applications, mesures diverses, etc.). <br>
Il permet de discerner les problèmes de performance des ressources.</p>
<ul>
<li>Site web : <a href="http://munin-monitoring.org/" rel="external">http://munin-monitoring.org/</a></li>
<li>Version : 2.0.49</li>
<li>OpenBSD : 6.6</li>
<li>Services : munin_node</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>Il est toujours utile de lire les documentations <code>pkg-readmes</code> fournies ;
celles disponibles sont dans <code>/usr/local/share/doc/pkg-readmes/</code>, à-propos de :</p>
<ul>
<li>munin-node</li>
<li>la documentation officielle :
<ul>
<li><a href="http://munin-monitoring.org/wiki/Documentation" rel="external">http://munin-monitoring.org/wiki/Documentation</a></li>
<li><a href="http://munin.readthedocs.org/" rel="external">http://munin.readthedocs.org/</a></li>
</ul>
</li>
<li>la FAQ officielle : <a href="http://munin-monitoring.org/wiki/faq" rel="external">http://munin-monitoring.org/wiki/faq</a></li>
</ul>
<h2 id="installation">Installation</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# pkg_add munin-node
</span></span></code></pre></div><p>Pour information, cela installe en dépendance quelques paquets de plus, dont
<code>p5-Net-CIDR</code>. <br>
<em>Ce paquet est utile pour la configuration de l&rsquo;option <code>cidr_allow</code> dans le
<a href="/fr/monitor/openbsd-munin-node/#munin-nodeconf">fichier de configuration du nœud de munin</a> ; s&rsquo;il n&rsquo;est pas
installé, faites-le !</em></p>
<p>Si vous désirez le support des moniteurs 






















































































<span lang="en">SNMP <em>(Simple Network Management Protocol)</em></span>
























, il faut installer
le paquet <code>p5-Net-SNMP</code>.</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration est <code>/etc/munin/munin-node.conf</code>.</p>
<p>Une fois configuré, il est nécessaire de démarrer le service de munin :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# rcctl enable munin_node
</span></span><span style="display:flex;"><span>:# rcctl start munin_node
</span></span></code></pre></div><h3 id="munin-nodeconf">munin-node.conf</h3>
<p>Ce fichier de configuration du nœud, <em>le client si vous préférez</em>, est simple à
paramétrer.</p>
<p>Vous pouvez changer principalement :</p>
<ul>
<li>
<p><code>global_timeout</code> : le délai timeout pour toute transaction. <br>
Par défaut, c&rsquo;est une période de 15 minutes ; à écrire en nombre de secondes.</p>
</li>
<li>
<p><code>timeout</code> : c&rsquo;est le timeout de connexion pour les plugins. <br>
Par défaut, de 60 secondes.</p>
</li>
<li>
<p><code>host_name</code> : le nom de votre hôte</p>
</li>
<li>
<p><code>allow</code> : permettre la connexion</p>
</li>
<li>
<p><code>host</code> : nom d&rsquo;hôte ou adresse ip à surveiller - préférez à changer par
<code>127.0.0.1</code> et/ou <code>::1</code>.</p>
</li>
<li>
<p><code>port</code> : le numéro du port d&rsquo;écoute, par défaut : <code>4949</code></p>
</li>
</ul>
<p><em>D&rsquo;autres variables sont configurables ; à vous d&rsquo;éditer le fichier et de vous
renseigner pour savoir quoi paramétrer !</em></p>
<hr>
<p>Pour finir, il est recommandé d&rsquo;exécuter le script de configuration du nœud munin, à savoir :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# munin-node-configure --shell --suggest | sh
</span></span></code></pre></div><h3 id="newsyslogconf">newsyslog.conf</h3>
<p>Il est nécessaire de modifier le fichier de configuration du journal
<code>/etc/newsyslog.conf</code> pour créer une rotation des journaux générés par munin.</p>
<p>Ajoutez-y :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># munin-node</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/log/munin/munin-node.log   root:wheel      644  7     250  *     Z</span>
</span></span></code></pre></div><h3 id="les-plugins">Les plugins</h3>
<ul>
<li>Les plugins peuvent être gérés par la commande <code>munin-node-configure --shell</code></li>
<li>Pour connaître la configuration d&rsquo;un plugin : <code>munin-run nom-plugin config</code></li>
<li>Pour tester le fonctionnement d&rsquo;un plugin : <code>munin-run nom-plugin</code></li>
</ul>
<p>Pour information, le répertoire est <code>/usr/local/libexec/munin/plugins/</code> ; pour
les activer, il suffit de faire un lien symbolique d&rsquo;un plugin en particulier
vers <code>/etc/munin/plugins</code>, puis de redémarrer les services de munin.</p>
<p>Certains plugins nécessitent une configuration supplémentaire, inscrite dans
les commentaires d&rsquo;entêtes du script. <br>
Il est alors nécessaire de modifier le fichier <code>/etc/munin/plugin-conf.d/openbsd-packages</code>
en ajoutant les informations nécessaires.</p>
<p>C&rsquo;est le cas des plugins suivants :</p>
<h4 id="plugin-http_loadtime">plugin http_loadtime</h4>
<ul>
<li>Options de configuration :
<ul>
<li><code>requisites</code> : <strong><span class="red">n'activer cette option que sur du flux
    HTTP, et non HTTPS !</span>
</strong></li>
</ul>
</li>
<li>WebAdmin : cf, section <code>network</code> : <code>HTTP loadtime of a page</code></li>
</ul>
<p>Permet de surveiller l&rsquo;accès à un site web, soit la page d&rsquo;acceuil, soit une
page dédiée.</p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[http_loadtime]</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">env.target http://huc.fr.eu.org,http://huc.fr.eu.org/fr/sys/openbsd/munin-monitoring-openbsd/</span>
</span></span><span style="display:flex;"><span>   <span style="color:#776e71">#env.requisites true</span>
</span></span></code></pre></div><h4 id="plugin-intr">plugin intr</h4>
<ul>
<li>WebAdmin : cf, section <code>system</code> : <code>Interrupt activity</code></li>
</ul>
<p>Relatif aux différentes interruptions d&rsquo;activités - spécifique à OpenBSD.</p>
<h4 id="plugins-nginx_">plugins nginx_*</h4>
<ul>
<li>WebAdmin : cf, section dédiée <code>nginx</code></li>
</ul>
<p>Non seulement, il faut modifier le fichier <code>openbsd-packages</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[nginx*]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">env.url http://localhost/nginx_status</span>
</span></span></code></pre></div><p>Mais en plus, il faut rajouter une configuration serveur au serveur web nginx. <br>
<span class="red">Il n'est donc pas possible de le monitorer avec httpd.</span>
</p>
<h4 id="plugins-pf_">plugins pf_*</h4>
<ul>
<li>
<p>Options de configuration :</p>
<ul>
<li><code>user</code> : <code>root</code></li>
<li><code>do_searches</code> : <code>false</code> ou <code>true</code> pour permettre les interrogations
adéquates. Certains plugins <strong>pf_</strong> peuvent nécessiter l&rsquo;ajout de la
variable d&rsquo;environnement</li>
</ul>
</li>
<li>
<p>WebAdmin : cf, section dédiée <code>pf</code></p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[pf_*]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">user root</span>
</span></span><span style="display:flex;"><span>  <span style="color:#776e71">#env.do_searches yes</span>
</span></span></code></pre></div><h4 id="plugin-samba">plugin samba</h4>
<ul>
<li>Options de configuration :
<ul>
<li><code>user</code> : <code>root</code></li>
<li><code>smbstatus</code> : restituer le chemin vers le binaire ad hoc</li>
<li><code>ignoreipcshare</code> : <code>false</code> ou <code>true</code> pour ignorer ou non les partages IPC$</li>
</ul>
</li>
<li>WebAdmin : cf, section dédiée <code>samba</code></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[samba]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">user root</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">env.smbstatus /usr/local/bin/smbstatus</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">env.ignoreipcshare 1</span>
</span></span></code></pre></div><h4 id="plugins-snmp">plugins SNMP</h4>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il semble que Munin ne soit pas directement capable de converser avec SNMPv3 en
authentification forte !</div>

<ul>
<li>
<p>Options de configuration :</p>
<ul>
<li>plusieurs options d&rsquo;environnement sont disponibles dont celles montrées
dans le fichier d&rsquo;exemple</li>
</ul>
</li>
<li>
<p>WebAdmin : cf, section dédiée <code>snmp</code></p>
</li>
</ul>
<p><span class="IMP red">Recommandations :</span></p>
<ul>
<li>
<p>À moins d&rsquo;utiliser SNMP v3 qui permet l&rsquo;authentification, le chiffrement,
donc la confidentialité du flux et des données, SNMP n&rsquo;est pas sécurisé.</p>
</li>
<li>
<p>Il est fortement recommandé de lire la documentation officielle de perl : <code>perldoc Munin::Plugin::SNMP</code></p>
</li>
<li>
<p>Dans tous les cas, la variable d&rsquo;environnement <code>community</code> ne devrait pas
être paramétrée sur <code>public</code>.</p>
</li>
</ul>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[snmp_*]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">env.warning 10</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">env.critical 5  # need for _print_*</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">env.version 2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">env.community private</span>
</span></span></code></pre></div><h3 id="la-partie-serveur">La partie serveur</h3>
<p>Une fois que cela est fait, il faut modifier le
<a class="inside" href="/fr/sys/openbsd/munin-server/#munin-conf" title="Lien interne vers l&#39;article : ''">fichier de configuration du serveur</a>
 pour lui
<a class="inside" href="/fr/sys/openbsd/munin-server/#ajouter-un-nc593ud" title="Lien interne vers l&#39;article : ''">ajouter votre nœud munin</a>
…</p>
<h3 id="packet-filter">Packet-Filter</h3>
<p>Concernant les règles pour 







































































<span lang="en">PF <em>(Packet Filter)</em></span>







































, il faut ouvrir en entrée et sortie,
vers et depuis le serveur munin :</p>
<ul>
<li>pour Munin lui-même : <code>4949/tcp</code></li>
<li>pour SNMP : <code>161</code>, <code>162</code> en <code>udp</code> et <code>tcp</code> - cela dépend de votre configuration
<a class="tag" href="/fr/tags/snmp">SNMP</a>
, bien sûr.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mettre en place un nœud Munin, un client, pour monitorer sa station OpenBSD]]></summary>
        <published>2019-11-22T20:05:30+01:00</published>
        <updated>2025-11-11T15:44:28+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:97da452e-d8ba-272a-0aad-9729f5058aa0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/snmp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: snmp : client SNMP sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="snmp" scheme="http://doc.huc.fr.eu.org/fr/tags/snmp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>snmp</strong> est le client 






















































































<span lang="en">SNMP <em>(Simple Network Management Protocol)</em></span>
























 par défaut sous OpenBSD, intégré dans
le système de base depuis 6.6 !</p>
<p><em>Il est bien sûr nécessaire qu&rsquo;un agent soit installé, configuré sur la
machine à interroger. Sous OpenBSD, c&rsquo;est le service natif <a class="tag" href="/fr/tags/snmpd">snmpd</a>
.</em></p>
<h2 id="documentation">Documentation</h2>
<p>La documentation se fait au-travers du manpage, tels que :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/snmp" title="Page du Manuel OpenBSD pour : snmp">snmp</a>
</li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<p>Premier aspect qui &ldquo;saute aux yeux&rdquo; est que <strong>snmp</strong> est fourni avec un
ensemble de sous-commandes, qui ont leurs propres options.</p>
<p>Pour information : les <strong>



































































<span lang="en">OID <em>(Object Identifier)</em></span>











































</strong> sont des identifiants d&rsquo;objets.</p>
<h3 id="description-des-sous-commandes">Description des sous commandes</h3>
<ul>
<li><code>snmp get</code> pour récupèrer le varbind 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































 depuis un agent 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























. <br>
Il est possible de spécifier plusieurs 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































.</li>
<li><code>snmp getnext</code> pour récupèrer le varbind qui suit l&rsquo;




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































 requis. <br>
Il est aussi possible d&rsquo;en spécifier plusieurs.</li>
<li><code>snmp walk</code> récupère toutes les branches d&rsquo;un 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































.</li>
<li><code>snmp bulkget</code> récupère les 10 prochains varbind suivant chaque 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































.</li>
<li><code>snmp bulkwalk</code> récupère tous les varbind qui sont des branches de l&rsquo;




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































.</li>
<li><code>snmp set</code> permet de définir un ou plusieurs varoid, ainsi que son format de
type de données.</li>
<li><code>snmp trap</code> envoie un message de capture à un agent.</li>
<li><code>snmp mibtree</code> permet de faire un dump <em>(une sauvegarde)</em> de l&rsquo;arborescence
des objets compilés au format MIB.</li>
</ul>
<p>Les deux sous commandes <code>bulk*</code>, ainsi que <code>trap</code> ne sont fonctionnelles
qu&rsquo;à partir de 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























v2.</p>
<p>Pour info, la sous commande <code>get</code> est aussi utile pour récupèrer les
messages d&rsquo;erreurs.</p>
<h3 id="snmp-v1">SNMP v1</h3>
<p>Oui, c&rsquo;est possible ; mais du fait que c&rsquo;est une version &ldquo;historique&rdquo;,
qu&rsquo;il n&rsquo;est plus recommandé de l&rsquo;utiliser, passons à la suite…</p>
<h3 id="snmp-v2">SNMP v2</h3>
<p>Il n&rsquo;y a pas de réelle sécurité avec SNMPv2. Elle se base principalement
sur l&rsquo;option <code>community</code> et les deux options <code>read-*</code>.</p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ snmp walk -v 2c -c public <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysDescr
</span></span></code></pre></div><p>Cet exemple nous montre l&rsquo;interrogation d&rsquo;un agent sur le protocole <code>v2c</code>
faisant partie de la communauté <code>public</code>.</p>
<p>Un petit mot sur l&rsquo;option <code>community</code>, ne cherchez pas à la faire fonctionner
avec 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























v3, elle a été supprimée du protocole.</p>
<h3 id="snmp-v3">SNMP v3</h3>
<p>Les options principales sont :</p>
<ul>
<li><code>-A</code> spécifie le mot de passe utilisateur de l&rsquo;agent à interroger.</li>
<li><code>-a</code> spécifie le protocole de chiffrement lié à l&rsquo;option <code>-A</code>.
<ul>
<li>Par défaut, l&rsquo;option <code>-a</code> est paramétrée sur <code>MD5</code>. <br>
<em>Attention, l&rsquo;option équivalente pour le service snmpd <code>hmac</code> est,
elle, basée sur <code>hmac-sha1</code>. Donc, dans le cas d&rsquo;un agent SNMPd
fonctionant sous OpenBSD configuré par défaut à interroger, il faudra
veiller à spécifier <code>SHA1</code></em>.</li>
</ul>
</li>
<li><code>-l</code> spécifie le niveau de sécurité. Par défaut, la valeur est <code>noAuthNoPriv</code>.
<ul>
<li><code>authNoPriv</code> est requise par l&rsquo;une des deux options <code>-A</code> ou <code>-k</code>.</li>
<li><code>authPriv</code> est requise par l&rsquo;une des deux options <code>-K</code> ou <code>-X</code>.</li>
</ul>
</li>
<li><code>-u</code> spécifie le nom de l&rsquo;utilisateur</li>
<li><code>-v</code> spécifie la version du protocole SNMP utilisé</li>
<li><code>-X</code> spécifie le mot de passe de confidentialité de l&rsquo;utilisateur</li>
<li><code>-x</code> spécifie le protocole de chiffrement de confidentialité. Les options
sont <code>des</code> ou <code>aes</code>.</li>
</ul>
<p>Ces options sont utiles voire nécessaires pour faire de
l&rsquo;<a href="/fr/sys/openbsd/snmp/#authentification-forte">authentification dite forte</a>.</p>
<p>Il y a bien sûr d&rsquo;autres options possibles :</p>
<ul>
<li>certaines ne sont pas nécessaires d&rsquo;être généralement spécifiées,
c&rsquo;est le cas de <code>-E</code>, <code>-e</code>,  <code>-n</code>, <code>-Z</code>.</li>
<li>les options <code>-K</code>, <code>-k</code> <em>(ces deux dernières options sont l&rsquo;équivalent
des options <code>-A</code> et <code>-X</code> mais encodées sous forme hexadécimale)</em>.</li>
<li>certaines sont spécifiques à l&rsquo;usage des sous commandes <code>bulk*</code>, <code>walk</code>.</li>
<li>pour finir, il est possible de cibler les protocoles réseaux que sont
<code>udp</code>, <code>tcp</code>, (et leur équivalent IPv6 : <code>upd6</code> et <code>tcp6</code>) ou <code>unix</code>.
Les adresses IPv6 doivent être mises entre crochets <code>{ }</code>.</li>
</ul>
<p>Lire le manpage 
<a class="man" href="https://man.openbsd.org/snmp" title="Page du Manuel OpenBSD pour : snmp">snmp</a>
 pour en savoir plus sur l&rsquo;utilité des
ces options.</p>
<p>Ci-dessous, retrouvez quelques exemples d&rsquo;utilisation avec le protocole
SNMPv3. Il est bien entendu que nous n&rsquo;abordons pas la partie de la
configuration de l&rsquo;agent interrogé. Sous <a class="tag" href="/fr/tags/openbsd">OpenBSD</a>
, la
configuration d&rsquo;un agent 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























 se fait par le biais du service
<a class="tag" href="/fr/tags/snmpd">SNMPd</a>
.</p>
<p>Dans chaque cas, les paramètres utilisés sont liés à ceux configurés dans
le service SNMPd.</p>
<h3 id="sans-authentification">Sans authentification</h3>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ snmp walk -u <span style="color:#48b685">&#34;test&#34;</span> -v <span style="color:#f99b15">3</span> <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysDescr
</span></span></code></pre></div><p>Dans cet exemple, nous interrogeons l&rsquo;agent avec un nom d&rsquo;utilisateur
nommé <code>test</code>, sans aucun niveau de sécurité.</p>
<h3 id="authentification-simple">Authentification simple</h3>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ snmp walk -A <span style="color:#48b685">&#34;secret007&#34;</span> -a SHA -l authNoPriv -u <span style="color:#48b685">&#34;uauth&#34;</span> -v <span style="color:#f99b15">3</span> 192.168.1.3 sysdescr
</span></span></code></pre></div><p>Ici, nous interrogeons l&rsquo;agent ayant pour adresse <code>192.168.1.3</code> avec un
nom utilisateur <code>uauth</code> , une clé d&rsquo;authentification <code>secret007</code> et un
niveau de sécurité spécifié à <code>authNoPriv</code>.</p>
<h3 id="authentification-forte">Authentification forte</h3>
<p>Quelques mots sur l&rsquo;authentification forte : elle est à favoriser
IMPÉRATIVEMENT !</p>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ snmp walk -A <span style="color:#48b685">&#34;zx4pyrfyeu5x5c3kxqirhtsxksbmawju&#34;</span> -a SHA-512 -l authPriv -u <span style="color:#48b685">&#34;uenc&#34;</span> -v <span style="color:#f99b15">3</span> -X <span style="color:#48b685">&#34;XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz&#34;</span> -x aes <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysdescr
</span></span></code></pre></div><p>Dans cet exemple, nous interrogeons localement l&rsquo;agent,</p>
<ul>
<li>avec un utilisateur nommé <code>uenc</code>,</li>
<li>une clé d&rsquo;authentification &ldquo;<code>zx4pyrfyeu5x5c3kxqirhtsxksbmawju</code>&rdquo; basée
sur le protocole de chiffrement <code>SHA-512</code>,</li>
<li>un niveau de sécurité sur <code>authPriv</code>,</li>
<li>le mot de passe de l&rsquo;utilisateur &ldquo;<code>XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz</code>&rdquo;
basé sur le protocole de chiffrement <code>aes</code>.</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="erreur--usmstatsdecryptionerrors0">Erreur : <code>usmStatsDecryptionErrors.0</code></h3>
<p>Le protocole de chiffrement que vous utilisez n&rsquo;est pas celui attendu
par l&rsquo;agent interrogé. Corrigez la valeur de votre option <code>-x</code>.</p>
<h3 id="erreur--usmstatsunsupportedseclevels0">Erreur : <code>usmStatsUnsupportedSecLevels.0</code></h3>
<p>Le niveau de sécurité que vous cherchez à utiliser n&rsquo;est pas celui attendu
par l&rsquo;agent interrogé. Corrigez la valeur de votre option <code>-l</code>.</p>
<h3 id="erreur--usmstatswrongdigests0">Erreur : <code>usmStatsWrongDigests.0</code></h3>
<p>Le protocole de chiffrement que vous utilisez n&rsquo;est pas celui attendu
par l&rsquo;agent interrogé. Corrigez la valeur de votre option <code>-a</code>.</p>
<h3 id="message----no-such-object-available-on-this-agent-at-this-oid">Message : <code>*** = No Such Object available on this agent at this OID</code></h3>
<p>Vous essayez de parcourir un arbre avec la sous commande <code>get</code>,
n&rsquo;est-ce pas !? <br>
Alors, soit vous recommencez en :</p>
<ul>
<li>utilisant la sous commande <code>walk</code></li>
<li>précisant un 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































 particulier</li>
</ul>
<h3 id="message--received-report">Message : <code>Received report:</code></h3>
<p>Vous venez de parcourir un arbre avec la sous commande <code>walk</code>, et vous
avez pour retour juste ce message <code>Received report:</code> sans rien de plus.</p>
<p>Utilisez la sous commande <code>get</code> à la place, cela vous permettra d&rsquo;obtenir
le message d&rsquo;erreur adéquat.</p>
<h3 id="message--snmp-invalid-privacy-protocol-specified-after--3x-flag">Message : <code>snmp: Invalid privacy protocol specified after -3x flag:</code></h3>
<p>Le niveau du protocole de sécurité que vous avez spécifié est incorrect.
Corrigez la valeur de votre option <code>-l</code>.</p>
<h3 id="message--snmp--unknown-object-identifier">Message : <code>snmp: ***: Unknown object identifier</code></h3>
<p>Vous avez spécifié un 




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































 inconnu. Vérifiez et corrigez
l&rsquo;




































































<abbr lang="en" title="Object Identifier">OID</abbr>











































 recherché.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment activer et configurer le client SNMP sous OpenBSD, et si possible le faire de façon sécurisé]]></summary>
        <published>2019-11-21T16:03:44+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:91303d95-cb1a-7999-0ab5-ee5bef625431</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/openbsd-snmpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Snmpd : Monitorer OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="snmpd" scheme="http://doc.huc.fr.eu.org/fr/tags/snmpd/" />
        <category term="snmp" scheme="http://doc.huc.fr.eu.org/fr/tags/snmp/" />
        <category term="serveur" scheme="http://doc.huc.fr.eu.org/fr/tags/serveur/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base <strong>snmpd</strong> qui est le
démon du service 






















































































<span lang="en">SNMP <em>(Simple Network Management Protocol)</em></span>
























.</p>
<ul>
<li>OpenBSD : 6.6</li>
<li>Service : snmpd</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>La documentation se fait au-travers des différents manpages, tels que :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/snmpd.8" title="Page du Manuel OpenBSD pour : snmpd">snmpd(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/snmpd.conf.5" title="Page du Manuel OpenBSD pour : snmpd.conf">snmpd.conf(5)</a>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>La configuration du serveur <strong>snmpd</strong> se fait, <em>à minima</em>, au-travers d&rsquo;un seul
fichier de configuration, à créer : <code>/etc/snmpd.conf</code>.</p>
<p>Il existe trois versions du protocol :</p>
<ul>
<li>la v1 est l&rsquo;historique à ne plus utiliser ;</li>
<li>la v2 apporte des prémices de sécurité ;</li>
<li>la v3 est la plus sécurisante, néanmoins, il faut utiliser les niveaux de
sécurité et de chiffrement les plus forts. <br>
<em>(Pour info, dans certaines conditions, la v3 est aussi faillible et
sujette à vulnérabilités)</em>.</li>
</ul>
<p>Après avoir écrit le fichier de configuration, il faut donner les droits
d&rsquo;exécution adéquates et utilisateur au fichier de configuration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# chown root:_snmpd /etc/snmpd.conf
</span></span><span style="display:flex;"><span>:# chmod <span style="color:#f99b15">0600</span> /etc/snmpd.conf
</span></span></code></pre></div><h3 id="configuration-globale">Configuration Globale</h3>
<p>Plusieurs options peuvent être paramétrées :</p>
<ul>
<li>
<p><code>filter-routes</code> (<strong>yes</strong>|<strong>no</strong>): permet au noyau de filter les messages de
mise à jour des routes dans le socket.</p>
</li>
<li>
<p><code>listen on</code> <em>address</em> [<strong>tcp</strong>|<strong>udp</strong>]: spécifie l&rsquo;adresse locale qui doit
écouter les messages 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























 entrants. <br>
<em>Il est possible de la spécifier plusieurs fois</em>. Les deux protocoles
<strong>




























































































<span lang="en">TCP <em>(Transfer Control Protocol)</em></span>


















</strong> et <strong>




































































































<span lang="en">UDP <em>(User Datagram Protocol)</em></span>










</strong> sont gérés.</p>
</li>
<li>
<p><code>read-only</code> : spécifie la communauté autorisée en lecture seule. <br>
Par défaut, la valeur est <code>public</code></p>
</li>
<li>
<p><code>read-write</code> (<strong>community</strong> <em>string</em> | <strong>disabled</strong>) : Soit spécifie la
communauté autorisée en lecture et écriture, soit désactive l&rsquo;écrite
définitivement. <br>
Par défaut, la valeur est <code>private</code></p>
</li>
<li>
<p><code>seclevel</code> : spécifie le niveau le plus bas de sécurité que snmpd(8) accepte. <br>
Par défault, la valeur est <code>none</code>. Si l&rsquo;une des deux autres options <code>auth</code>
ou <code>enc</code> est choisie, snmpd(8) n&rsquo;acceptera que les requêtes SNMPv3. <code>enc</code>
oblige à ce que les messages soient chiffrés et une authentification valide,
autrement ils seront supprimés.</p>
</li>
<li>
<p>Il existe aussi l&rsquo;option <code>socket</code>, les différentes options <code>system</code> et celles
relatives à <code>trap</code>. Je renvoie au manpage ;)</p>
</li>
</ul>
<p>Les deux options <code>read_*</code> ne servent QUE pour une configuration 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























 v2.</p>
<h3 id="macros">Macros</h3>
<p>Des macros peuvent être définies. Considérez-les comme des variables. On ne
peut utiliser des mots clés réservés. Elles commencent forcément par une lettre,
un chiffre ou le symbole &lsquo;<code>_</code> &rsquo; suivi de tout autre caractère.</p>
<h3 id="configuration-des-utilisateurs">Configuration des utilisateurs</h3>
<p>Avec 























































































<abbr lang="en" title="Simple Network Management Protocol">SNMP</abbr>
























v3, Il est possible de définir plusieurs utilisateurs
par le biais de
l&rsquo;option <code>user</code>, tel que :</p>
<ul>
<li>
<p><code>user</code> <em>name</em> <strong>authkey</strong> <em>key</em> <strong>auth</strong> <em>hmac</em> <strong>enckey</strong> <em>key</em> <strong>enc</strong> <em>cipher</em></p>
<ul>
<li>
<p><code>authkey</code> est requis pour authentifier les messages en spécifiant une clé.
Si la clé est omise, pas d&rsquo;authentification.</p>
</li>
<li>
<p><code>auth</code> <em>hmac</em> permet de cibler l&rsquo;algorithme HMAC à utiliser. <br>
Par défaut, la valeur est <code>hmac-sha1</code>. La valeur la plus forte est
<code>hmac-sha512</code>.</p>
</li>
<li>
<p><code>enckey</code> <em>key</em> est la clé de chiffrement utilisé pour chiffrer et
déchiffrer les messages dans un soucis de confidentialité. Sans,
le compte utilisateur n&rsquo;acceptera jamais l&rsquo;entrée des messages ou ne
chiffrera pas les messages sortants.</p>
</li>
<li>
<p><code>enc</code> <em>cipher</em> est l&rsquo;algorithme utilisé. <br>
Par défaut, sa valeur est <code>des</code>. Sa valeur la plus forte est <code>aes</code>.</p>
</li>
</ul>
</li>
</ul>
<p>Il faut bien comprendre que le nom de l&rsquo;utilisateur, les caractères donnant la
valeur des clés <code>key</code> sont des choix purement arbitraires. À vous de les
spécifier…</p>
<h3 id="configuration-des-oid">Configuration des OID</h3>
<p>Les <strong>OID</strong> sont les identifiants des objets. Je renvoie au manpage, si besoin
de les gérer.</p>
<h2 id="utilisation">Utilisation</h2>
<ul>
<li>Le service se nomme logiquement : <code>snmpd</code></li>
<li>L&rsquo;option de test de configuration : <code>-n</code></li>
</ul>
<p>Ainsi la commande <code>snmpd -n</code> permettra de s&rsquo;assurer de la validité de l&rsquo;ensemble
de la configuration, à tout moment.</p>
<p>À chaque modification du <a href="/fr/monitor/openbsd-snmpd/#configuration">fichier de configuration</a>, il faudra
relancer le service ad hoc.</p>
<h3 id="snmp-v2">SNMP v2</h3>
<p>Pour débuter, commençons par :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">listen on 192.168.1.3 udp</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">read-only community macompub</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">read-write community macompriv</span>
</span></span></code></pre></div><p>À minima, nous n&rsquo;avons besoin de rien de plus. C&rsquo;est très basique et permet de
tester/s&rsquo;assurer du bon fonctionnement, de la bonne compréhension.</p>
<p>Testons la réponse :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ snmp walk -v 2c -c macompub <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysDescr
</span></span><span style="display:flex;"><span>sysDescr.0 <span style="color:#5bc4bf">=</span> STRING: OpenBSD omv.huc.fr.eu.org 6.6 GENERIC.MP#2 amd64
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ snmp walk -v 2c -c macompub <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> ifName
</span></span><span style="display:flex;"><span>ifName.1 <span style="color:#5bc4bf">=</span> STRING: em0
</span></span><span style="display:flex;"><span>ifName.2 <span style="color:#5bc4bf">=</span> STRING: enc0
</span></span><span style="display:flex;"><span>ifName.3 <span style="color:#5bc4bf">=</span> STRING: lo0
</span></span><span style="display:flex;"><span>ifName.4 <span style="color:#5bc4bf">=</span> STRING: pflog0
</span></span></code></pre></div><p>Ce sont des exemples d&rsquo;interrogation et réponses.</p>
<h3 id="snmp-v3">SNMP v3</h3>
<h4 id="sans-sécurité">Sans sécurité</h4>
<p>Commençons avec un exemple sans sécurité :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">seclevel none</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">user &#34;test&#34;</span>
</span></span></code></pre></div><p>Après le rédémarrage du service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ snmp walk -u <span style="color:#48b685">&#34;test&#34;</span> -v <span style="color:#f99b15">3</span> <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysDescr
</span></span><span style="display:flex;"><span>sysDescr.0 <span style="color:#5bc4bf">=</span> STRING: OpenBSD omv.huc.fr.eu.org 6.6 GENERIC.MP#2 amd64
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ snmp walk -u <span style="color:#48b685">&#34;test&#34;</span> -v <span style="color:#f99b15">3</span> <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> ifName
</span></span><span style="display:flex;"><span>ifName.1 <span style="color:#5bc4bf">=</span> STRING: em0
</span></span><span style="display:flex;"><span>ifName.2 <span style="color:#5bc4bf">=</span> STRING: enc0
</span></span><span style="display:flex;"><span>ifName.3 <span style="color:#5bc4bf">=</span> STRING: lo0
</span></span><span style="display:flex;"><span>ifName.4 <span style="color:#5bc4bf">=</span> STRING: pflog0
</span></span></code></pre></div><h4 id="utilisateur-authentifié">Utilisateur authentifié</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">seclevel auth</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">user &#34;uauth&#34; authkey &#34;secret007&#34;</span>
</span></span></code></pre></div><p>Après le rédémarrage du service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ snmp walk -A <span style="color:#48b685">&#34;secret007&#34;</span> -a SHA -l authNoPriv -u <span style="color:#48b685">&#34;uauth&#34;</span> -v <span style="color:#f99b15">3</span> 192.168.47.3 sysdescr
</span></span><span style="display:flex;"><span>sysDescr.0 <span style="color:#5bc4bf">=</span> STRING: OpenBSD omv.huc.fr.eu.org 6.6 GENERIC.MP#2 amd64
</span></span></code></pre></div><h4 id="authentification-forte">Authentification forte</h4>
<p>Configurons le serveur par un exemple fort :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">listen on 192.168.1.3 tcp</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">seclevel enc</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">user &#34;uenc&#34; authkey &#34;zx4pyrfyeu5x5c3kxqirhtsxksbmawju&#34; auth hmac-sha512 enckey &#34;XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz&#34; enc aes</span>
</span></span></code></pre></div><p>Après le redémarrage du service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ snmp walk -A <span style="color:#48b685">&#34;zx4pyrfyeu5x5c3kxqirhtsxksbmawju&#34;</span> -a SHA-512 -l authPriv -u <span style="color:#48b685">&#34;uenc&#34;</span> -v <span style="color:#f99b15">3</span> -X <span style="color:#48b685">&#34;XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz&#34;</span> -x aes <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span> sysdescr
</span></span><span style="display:flex;"><span>sysDescr.0 <span style="color:#5bc4bf">=</span> STRING: OpenBSD omv.huc.fr.eu.org 6.6 GENERIC.MP#2 amd64
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ snmp walk -A <span style="color:#48b685">&#34;zx4pyrfyeu5x5c3kxqirhtsxksbmawju&#34;</span> -a SHA-512 -l authPriv -u <span style="color:#48b685">&#34;uenc&#34;</span> -v <span style="color:#f99b15">3</span> -X <span style="color:#48b685">&#34;XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz&#34;</span> -x aes  <span style="color:#815ba4">$(</span>hostname<span style="color:#815ba4">)</span>  ifname
</span></span><span style="display:flex;"><span>ifName.1 <span style="color:#5bc4bf">=</span> STRING: em0
</span></span><span style="display:flex;"><span>ifName.2 <span style="color:#5bc4bf">=</span> STRING: enc0
</span></span><span style="display:flex;"><span>ifName.3 <span style="color:#5bc4bf">=</span> STRING: lo0
</span></span><span style="display:flex;"><span>ifName.4 <span style="color:#5bc4bf">=</span> STRING: pflog0
</span></span></code></pre></div><h3 id="gestion-du-service">Gestion du service</h3>
<ul>
<li>activation : <code>rcctl enable snmpd</code></li>
<li>démarrage : <code>rcctl start snmpd</code></li>
</ul>
<p>Après avoir activé et démarré le service, il est possible de vérifier le
fonctionnement du service, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ps aux | grep snmpd
</span></span><span style="display:flex;"><span>_snmpd   <span style="color:#f99b15">41593</span>  0.0  0.1   <span style="color:#f99b15">772</span>  <span style="color:#f99b15">3124</span> ??  SU     10:32PM    0:00.07 snmpd: snmpe <span style="color:#5bc4bf">(</span>snmpd<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>root     <span style="color:#f99b15">55283</span>  0.0  0.0   <span style="color:#f99b15">820</span>  <span style="color:#f99b15">1492</span> ??  Ip     10:32PM    0:00.01 /usr/sbin/snmpd
</span></span><span style="display:flex;"><span>_snmpd   <span style="color:#f99b15">42220</span>  0.0  0.1   <span style="color:#f99b15">752</span>  <span style="color:#f99b15">2756</span> ??  Ip     10:32PM    0:00.02 snmpd: traphandler <span style="color:#5bc4bf">(</span>snmpd<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>root     <span style="color:#f99b15">80301</span>  0.0  0.0   <span style="color:#f99b15">332</span>  <span style="color:#f99b15">1256</span> p0  S+p    10:33PM    0:00.01 grep snmpd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ netstat -ant | grep snmp
</span></span><span style="display:flex;"><span>0xfffffd8105572100 stream      <span style="color:#f99b15">0</span>      <span style="color:#f99b15">0</span> 0xfffffd810e7e70e8                0x0                0x0                0x0 /var/run/snmpd.sock
</span></span></code></pre></div><p>Voilà, pour la partie serveur !</p>
<p>Et les clients ?</p>
<h3 id="les-clients">Les clients</h3>
<p>Depuis OpenBSD 6.6, le client natif est 
<a class="man" href="https://man.openbsd.org/snmp" title="Page du Manuel OpenBSD pour : snmp">snmp</a>
</p>
<p>Pour information, il y a sur chaque système OpenBSD, dans le répertoire
<code>/usr/share/snmp/mibs/</code> l&rsquo;ensemble de fichiers MIB qui renferment toutes
informations utiles :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ls -al /usr/share/snmp/mibs/
</span></span><span style="display:flex;"><span>total <span style="color:#f99b15">184</span>
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">2</span> root  wheel    <span style="color:#f99b15">512</span> Oct <span style="color:#f99b15">12</span> 18:34 ./
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">3</span> root  wheel    <span style="color:#f99b15">512</span> Oct <span style="color:#f99b15">12</span> 18:34 ../
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel   <span style="color:#f99b15">2331</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-BASE-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel   <span style="color:#f99b15">8805</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-CARP-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel   <span style="color:#f99b15">3283</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-MEM-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel  <span style="color:#f99b15">39486</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-PF-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel  <span style="color:#f99b15">18559</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-RELAYD-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel   <span style="color:#f99b15">4635</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-SENSORS-MIB.txt
</span></span><span style="display:flex;"><span>-r--r--r--  <span style="color:#f99b15">1</span> root  wheel   <span style="color:#f99b15">2547</span> Oct <span style="color:#f99b15">12</span> 18:34 OPENBSD-SNMPD-CONF.txt
</span></span></code></pre></div><p>Il peut être utile de les &ldquo;donner à manger&rdquo; aux différents clients des autres
systèmes de surveillance/métrologie/monitoring, tel <a class="tag" href="/fr/tags/nagios">Nagios</a>
,
<a class="tag" href="/fr/tags/munin">Munin</a>
, etc…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place le service de monitoring SNMPd sous OpenBSD]]></summary>
        <published>2019-11-20T22:43:39+01:00</published>
        <updated>2019-11-21T16:00:00+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5ad46ece-de32-b042-237c-99eae21ada94</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/httpd/httpd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: httpd : présentation du serveur HTTP d&#39;OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>OpenBSD</strong> intègre par défaut dans le système de base un serveur web,
nommé <strong>httpd</strong>, depuis 5.7.<br>
C&rsquo;est un serveur qui se veut sécurisé, tant par le fonctionnement chrooté
que par la séparation des privilèges, l&rsquo;usage de chiffrements forts, de
courbes elliptiques, et autres paramétres forts pour
<abbr title="Transport Layer Security">TLS</abbr>
, par défaut.</p>
<p><strong>httpd</strong> est un serveur <abbr title="HyperText Transfert Protocol">HTTP</abbr>
 de
fichiers statiques, qui supporte les appels directs ou asynchrones FastCGI
(soit par socket Unix - <em>c&rsquo;est mieux</em> -, soit par
<abbr title="Transfert Control Protocol">TCP</abbr>
/<abbr title="Internet Protocol">IP</abbr>
).
Il est bien sûr possible de gérer les connexions TLS, via la bibliothèque
LibreSSL, et fonctionne sur la double couche de protocole IPv4 et IPv6.</p>
<p>Une configuration flexible d&rsquo;hôtes virtuels est possible, soit par nom d&rsquo;hôte,
soit par adresse IP.</p>
<p>Enfin, la journalisation se fait soit via <code>syslog</code>, soit par des journaux
d&rsquo;accès et d&rsquo;erreurs dédiés aux différents hôtes virtuels.</p>
<p>Ce que ne gère pas <strong>httpd</strong> :</p>
<ul>
<li>
<p>les entêtes HTTP.</p>
</li>
<li>
<p>l&rsquo;URL Rewriting ?</p>
</li>
<li>
<p>Quoi d&rsquo;autres ?!</p>
</li>
<li>
<p>Site web : <a href="https://bsd.plumbing/" rel="external">https://bsd.plumbing/</a></p>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>La configuration du serveur httpd se fait, <em>à minima</em>, au-travers d&rsquo;un seul
fichier de configuration, à créer : <code>/etc/httpd.conf</code>.</p>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">prefork 3

types { include &#34;/usr/share/misc/mime.types&#34; }

server &#34;adr_ip&#34; {
    …
}
</code></pre><p>La configuration d&rsquo;hôte virtuel, étant à envisager, il est préférable de
créer un fichier par hôte et de l&rsquo;inclure dans le fichier de configuration
par le biais du mot clé <code>include</code>.</p>
<h3 id="configuration-globale">Configuration Globale</h3>
<p>Voici les paramètres de niveau global :</p>
<ul>
<li><code>chroot</code> : spécifie le répertoire 
<a class="man" href="https://man.openbsd.org/chroot.2" title="Page du Manuel OpenBSD pour : chroot">chroot(2)</a>
. S&rsquo;il n&rsquo;est pas
spécifié, il a pour valeur <code>/var/www/</code> qui est le répertoire home de
l&rsquo;utilisateur web <code>www</code>.</li>
<li><code>default type</code> : spécifie les types de média utilisés pour une extension
donnée ou un type de fichier. S&rsquo;il n&rsquo;est pas spécifié, le type par défaut
est <code>application/octect-stream</code>.</li>
<li><code>logdir</code> : spécifie le répertoire où les journaux seront écrits. Par défaut,
il fait référence au répertoire enfant <code>logs/</code> à l&rsquo;intérieur du chroot.</li>
<li><code>prefork</code> : le nombre de processus du serveur. Par défaut, httpd utilise
3 processus serveur. Augmenter cette valeur améliore la performance
et prévient les délais de connexion au serveur.</li>
</ul>
<h3 id="macros">Macros</h3>
<p>Des macros peuvent être définies. Considérez-les comme des variables. On
ne peut utiliser des mots clés réservés. Elles commencent forcément par
une lettre, un chiffre ou le symbole &lsquo;<code>_</code> &rsquo; suivi de tout autre caractère.</p>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">ip_ext=&#34;10.0.0.1&#34;

server &#34;default&#34; {
    listen on $ip_ext port 80
    …
}
</code></pre><p>Dans cet exemple, la macro est la variable <code>ip_ext</code> ; sa valeur étant <code>10.0.0.1</code>.</p>
<h3 id="les-hôtes-virtuels">Les Hôtes Virtuels</h3>
<p>La gestion des hôtes virtuels se fait dans chaque section <code>server</code>, en
déclarant le nom du serveur entre double-quotes.</p>
<p>Pour plus d&rsquo;informations, lire la section <a href="https://man.openbsd.org/httpd.conf.5#SERVERS" rel="external"><code>SERVERS</code></a> du manpage <code>httpd.conf(5)</code>.</p>
<h3 id="les-types-médias">Les Types Médias</h3>
<p>La section <code>types</code> configure les types de média supportés. Si rien n&rsquo;est
spécifié, par défaut, httpd gére les types de média pour :</p>
<ul>
<li><code>text/css</code>, <code>text/html</code>, <code>text/plain</code></li>
<li><code>image/gif</code>, <code>image/jpeg</code>, <code>image/png</code>, <code>image/svg+xml</code></li>
<li>ainsi qu&rsquo;<code>application/javascript</code>.</li>
</ul>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">types { include &#34;usr/share/misc/mime.types&#34; }
</code></pre><p>ou</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">types {
    text/css        css
    text/html       html htm
    text/plain      txt
    image/gif       gif
    image/jpeg      jpeg jpg
    image/png       png
    application/javascript  js
    application/xml     xml
}
</code></pre><ul>
<li>Avant de chercher à ajouter un nouveau type, assurez-vous qu&rsquo;il ne soit
pas déjà inclus dans le fichier <code>/usr/share/misc/mimes.types</code> ; si ce n&rsquo;est
pas le cas, ajoutez-le en suivant.*</li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<ul>
<li>Le service se nomme logiquement : <code>httpd</code></li>
<li>L&rsquo;option de test de configuration : <code>-n</code></li>
</ul>
<p>Ainsi la commande <code>httpd -n</code> permettra de s&rsquo;assurer de la validité de
l&rsquo;ensemble de la configuration, à tout moment.</p>
<p>Par convention/préférence, il est intéressant de créer un répertoire <code>/etc/httpd.d/</code>
dans lequel sera écrit les configurations serveurs des hôtes virtuels, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# mkdir -p /etc/httpd.d
</span></span></code></pre></div><p>Modification du fichier de configuration <code>/etc/httpd.conf</code> :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">types { include &#34;usr/share/misc/mime.types&#34; }
</code></pre><p>Puis utilisez le mot clé <code>include</code> pour ajouter la configuration d&rsquo;un hôte
virtuel au fur et à mesure des besoins, tel que</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">include &#34;etc/httpd.d/nom-de-domaine.conf&#34;
</code></pre><h3 id="gestion-des-logs">Gestion des logs</h3>
<p>La gestion des logs est intéressante.</p>
<ul>
<li>Vous ne voulez pas de log, indiquez <code>no log</code> dans votre section <code>server</code>.</li>
<li>Vous pouvez demander à 
<a class="man" href="https://man.openbsd.org/syslog.3" title="Page du Manuel OpenBSD pour : syslog">syslog(3)</a>
 d&rsquo;enregistrer la journalisation,
en lieu et place des journaux individualisés. <br>
Spécifiez tout simplement : <code>log syslog</code></li>
<li>Vous pouvez invoquer individuellement les logs d&rsquo;accès ou d&rsquo;erreur, tel que :</li>
</ul>
<pre tabindex="0"><code>log access &#34;nom-fichier-acces.log&#34;
log error  &#34;nom-fichier-erreurs.log&#34;
</code></pre><p>Néanmoins, sachez qu&rsquo;il est possible d&rsquo;intégrer les différentes options
entre crochets, tel que :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">log {
    access &#34;nom-fichier-acces.log&#34;
    error  &#34;nom-fichier-erreurs.log
}
</code></pre><p>Et, pour finir, vous pouvez y intégrer l&rsquo;option <code>style</code> qui va vous permettre
de définir le style de journalisation désiré, tel que :</p>
<ul>
<li><code>common</code> ou <code>combined</code> : ces deux styles imitent le format de journalisation
des standards des serveurs web Apache ou nginx. <code>common</code> est le type
par défaut, si aucun n&rsquo;est spécifié.</li>
<li><code>forwarded</code> étend le style <code>combined</code> en ajoutant deux champs d&rsquo;information
contenant la valeur des entêtes <code>X-Forwarded-For</code> et <code>X-Forwarded-Port</code>
<em>(respectivement, la première doit retourner l&rsquo;adresse ip du client,
la seconde celle du port de connexion sur le serveur)</em>. Intéressant
quand <strong>httpd</strong> est derrière un proxy web, tel nginx ou relayd.</li>
<li><code>connection</code> imite le format de journalisation du serveur 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
.
Chaque entrée du journal est un résumé de chaque connexion qui peut
contenir de multiples requêtes.</li>
</ul>
<h3 id="authentification-web">Authentification Web</h3>
<p><strong>httpd</strong> peut faire de l&rsquo;authentification web.</p>
<p>Dans un premier temps, il faut utiliser l&rsquo;outil 
<a class="man" href="https://man.openbsd.org/htpasswd.5" title="Page du Manuel OpenBSD pour : htpasswd">htpasswd(5)</a>
,
<em>(accessible nativement depuis OpenBSD 5.6)</em>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# cd /var/www/
</span></span><span style="display:flex;"><span>:# htpasswd nom-fichier identifiant
</span></span><span style="display:flex;"><span>Password:
</span></span><span style="display:flex;"><span>Retype Password:
</span></span></code></pre></div><p><span class="red">Par mesure de sécurité, ensuite, attribuez-lui des droits
en exécution <code>0400</code>, accessible rien que par l&rsquo;utilisateur web <code>www</code>.</span></p>
<p>Puis ensuite dans une des directives <code>location</code> ou <code>server</code>, ajoutez ce
qui ressemble à :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">authenticate &#34;! Acces sous Restriction !&#34; with &#34;/nom-fichier&#34;
</code></pre><h3 id="php-fpm">PHP-FPM</h3>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Attention, si vous mettez en place PHP et permettez la connexion en clair,
sur le protocole HTTP, il est recommandé fortement de mettre en frontal
<a class="inside" href="/fr/web/httpd/relayd-headers-httpd/#relayd-httpoxy" title="Lien interne vers l&#39;article : 'Relayd : Gestion des entêtes pour httpd'">relayd afin de lutter contre la faille Httpoxy</a>
!</div>

<p>Pour autant que vous avez installer PHP sur le serveur, <strong>httpd</strong> peut servir
du contenu PHP, par le biais de la directive <code>location</code>, tel que :</p>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">location &#34;*.php&#34; {
    fastcgi socket &#34;/run/php-fpm.sock&#34;
}
</code></pre><p>Il est nécessaire que le socket FastCGI corresponde bien à celui de PHP-FPM.</p>
<h3 id="slowcgi">Slowcgi</h3>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Attention, si vous mettez en place CGI et permettez la connexion en clair,
sur le protocole HTTP, il est recommandé fortement de mettre en frontal
<a class="inside" href="/fr/web/httpd/relayd-headers-httpd/#relayd-httpoxy" title="Lien interne vers l&#39;article : 'Relayd : Gestion des entêtes pour httpd'">relayd afin de lutter contre la faille Httpoxy</a>
!</div>

<p><strong>
<a class="man" href="https://man.openbsd.org/slowcgi.8" title="Page du Manuel OpenBSD pour : slowcgi">slowcgi(8)</a>
</strong> est un serveur FastCGI de connexion
<abbr title="Common Gateway Interface">CGI</abbr>
, <em>lui aussi intégré dans le système
de base d&rsquo;OpenBSD, depuis la version 5.4</em>.</p>
<p><strong>httpd</strong> peut servir du contenu CGI, disponible depuis le répertoire enfant
<code>cgi-bin/</code> du chroot web, par le biais de la directive <code>location</code>, tel que :</p>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">location &#34;/cgi-bin/*.cgi&#34; {
    fastcgi socket &#34;/run/slowcgi.sock&#34;
    root &#34;/&#34;
}
</code></pre><p>Là aussi, il est nécessaire que le nom du socket FastCGI corresponde bien.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : Il semble important de mettre en place une
<a href="/fr/web/httpd/httpd/#authentification-web">authentification web</a> pour protéger le contenu délivré
par les scripts CGI !</div>

<h3 id="tls">TLS</h3>
<p><strong>httpd</strong> prend très bien en charge la configuration TLS.</p>
<p>Exemple :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">listen on adresse_ip tls port 443
hsts preload
tls {
    certificate &#34;/etc/ssl/chezmoi.tld-fullchain.pem&#34;
    key &#34;/etc/ssl/private/chezmoi.tld.key&#34;
    ticket lifetime 3600
}
</code></pre><ul>
<li>La directive <code>hsts</code> active la gestion <strong>HTTP Strict Transport Security</strong>. <br>
Les options suivantes sont possibles :
<ul>
<li><code>max-age</code> en nombre de secondes - paramètre le temps maximum durant lequel
cet hôte peut être considéré comme hôte HSTS.</li>
<li><code>preload</code> confirme et authentifie que le site est autorisé à être inclu
dans la liste de préchargement des navigateurs web.</li>
<li><code>subdomains</code> signale que les sous-domaines doivent être considérés comme
hôtes HSTS. <br>
<span class="red">Il semble important par mesure de sécurité d'utiliser
        cette option lors de fonctionnement avec des sous-domaines, même si ces
        derniers ont leurs propres certificats TLS</span>
.</li>
</ul>
</li>
<li>La directive <code>tls</code> permet de spécifier la configuration TLS du serveur. Les
différentes options sont comprises dans les crochets. Les options suivantes
sont possibles :
<ul>
<li><code>certificate</code> - nécessaire - pour spécifier le certificat serveur, encodé
au format PEM.</li>
<li><code>key</code> - nécessaire - pour spécifier le fichier de clé privée, encodée lui
aussi au format PEM. <br>
<span class="red">ATTENTION : ce fichier doit absolument résider
        en-dehors du chroot web</span>
.</li>
<li>Il est possible de paramétrer :
<ul>
<li>les options de chiffrement <code>ciphers</code>,</li>
<li>les clés d&rsquo;échange <code>dhe</code>,</li>
<li>les courbes elliptiques <code>ecdhe</code> - <em>par défaut, sont actives : <code>X25519</code>,
<code>P-256</code> et <code>P-384</code></em> -,</li>
<li>une réponse <code>ocsp</code> - <em>il faudra générer un fichier OCSP au format DER
avec l&rsquo;outil 
<a class="man" href="https://man.openbsd.org/oscpcheck.8" title="Page du Manuel OpenBSD pour : oscpcheck">oscpcheck(8)</a>
</em> -,</li>
<li>de spécifier les <code>protocols</code> TLS - <em>sachant que seul TLSv1.2 est
actif par défaut</em> -</li>
<li>ainsi que la durée de vie du ticket de session <code>ticket lifetime</code> en
nombre de secondes - <em>qui par défaut est de 2 heures</em>.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><span class="IMP">Il ne sert à rien de spécifier une valeur d&rsquo;option par défaut,
puisque par défaut, sans écriture, c&rsquo;est la valeur qui lui est appliquée !</span></p>
<h3 id="auto-indexation">Auto-indexation</h3>
<p><strong>httpd</strong> peut faire de l&rsquo;auto-indexation de répertoire et ainsi afficher le
contenu d&rsquo;un répertoire en particulier. Ajoutez tout simplement, soit dans une
directive <code>server</code>, soit <code>location</code> :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">directory auto index
</code></pre><h2 id="documentation">Documentation</h2>
<h3 id="manpages">Manpages</h3>
<p>La documentation se fait au-travers des différents manpages, tels que :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
, 
<a class="man" href="https://man.openbsd.org/httpd.conf.5" title="Page du Manuel OpenBSD pour : httpd.conf">httpd.conf(5)</a>
</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Présentation du serveur web httpd natif sous OpenBSD]]></summary>
        <published>2019-11-17T01:08:30+01:00</published>
        <updated>2020-05-07T18:25:36+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:40c89672-3a49-4959-9579-8d76f9d1624f</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/openbsd-munin-server/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Munin : Monitorer OpenBSD avec httpd </title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="Munin" scheme="http://doc.huc.fr.eu.org/fr/tags/munin/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="serveur" scheme="http://doc.huc.fr.eu.org/fr/tags/serveur/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong>Munin</strong> est un outil de surveillance des ordinateurs. Il présente ces
informations par le biais d&rsquo;une interface web, qui visualise des graphiques
statiques, générés toutes les 5 minutes, par défaut. Un certain nombre de
plugins de monitoring divers sont utilisables sans gros effort.</p>
<p><strong>Munin</strong> permet de monitorer facilement la performance de tout matériel
informatique (ordinateurs, réseaux, applications, mesures diverses, etc.). <br>
Il permet de discerner les problèmes de performance des ressources.</p>
<ul>
<li>Site web : <a href="http://munin-monitoring.org/" rel="external">http://munin-monitoring.org/</a></li>
<li>Version : 2.0.49</li>
<li>OpenBSD : 6.6</li>
<li>Services : httpd + munin_node + munin_asyncd</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>Il est toujours utile de lire les documentations <code>pkg-readmes</code> fournies ;
celles disponibles sont dans <code>/usr/local/share/doc/pkg-readmes/</code>, à-propos de :</p>
<ul>
<li>munin-node</li>
<li>munin-server</li>
<li>la documentation officielle :
<ul>
<li><a href="http://munin-monitoring.org/wiki/Documentation" rel="external">http://munin-monitoring.org/wiki/Documentation</a></li>
<li><a href="http://munin.readthedocs.org/" rel="external">http://munin.readthedocs.org/</a></li>
</ul>
</li>
<li>la FAQ officielle : <a href="http://munin-monitoring.org/wiki/faq" rel="external">http://munin-monitoring.org/wiki/faq</a></li>
</ul>
<h2 id="installation">Installation</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# pkg_add munin-node munin-server
</span></span></code></pre></div><p>Un utilisateur <code>_munin</code> a été créé et le répertoire web, par défaut, est dans
<code>/var/www/htdocs/munin/</code>. Ce répertoire reçoit les droits de l&rsquo;utilisateur
<code>_munin</code> et du groupe web <code>www</code>.</p>
<p>Pour information, cela installe en dépendance quelques paquets de plus, dont
<code>p5-Net-CIDR</code> - <em>ce paquet est utile pour la configuration de l&rsquo;option
<code>cidr_allow</code> dans le <a href="/fr/monitor/openbsd-munin-server/#munin-nodeconf">fichier de configuration du nœud de munin</a> ;
s&rsquo;il n&rsquo;est pas installé, faites-le !</em></p>
<p>Si vous désirez le support des moniteurs 






















































































<span lang="en">SNMP <em>(Simple Network Management Protocol)</em></span>
























, il faut installer
le paquet <code>p5-Net-SNMP</code>.</p>
<h2 id="configuration">Configuration</h2>
<p>Deux fichiers de configuration principaux sont dans <code>/etc/munin</code> :</p>
<ul>
<li><code>munin.conf</code> relatif au serveur lui-même</li>
<li><code>munin-node.conf</code> relatif au nœud de surveillance local.</li>
</ul>
<p>Une fois, ces fichiers configurés, il est possible de démarrer les deux
services de munin.</p>
<h3 id="muninconf">munin.conf</h3>
<p>Généralement, il y a peu de choses à changer, néanmoins, pour informations,
certaines variables peuvent être configurées.</p>
<ul>
<li><code>dbdir</code> : répertoire de la base de donnée de munin</li>
<li><code>htmldir</code> : répertoire de destination des données graphiques générées.</li>
<li><code>logdir</code> : répertoire des journaux de munin</li>
<li><code>rundir</code> : répertoire où s&rsquo;exécute le processus munin.</li>
</ul>
<p>Si vous préférez une exécution du processus par cron plus que par script CGI,
vous pouvez modifier les deux variables <code>graph_strategy</code> et <code>html_strategy</code>.</p>
<p>Par défaut sera configurée une arborescence basique basée sur localhost,
tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[localhost]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">address 127.0.0.1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">user_node_name yes</span>
</span></span></code></pre></div><p>Si vous préférez une arborescence par nom de domaine, modifiez/commentez/ajoutez
<code>localhost</code> par le nom de domaine désiré, tel <code>huc.fr.eu.org</code>. Bien sûr, il est
possible de surveiller autant d&rsquo;hôtes que désiré.</p>
<p>Il est possible de gérer les différents nœuds par groupe ; cela permet de
regrouper les informations. Je vous renvoie aux documentations officielles et
autres manpages.</p>
<p>Les noms de nœuds, de groupe de nœuds ainsi que les adresses IPv6 doivent être
encadrés de <code>[ ]</code>.</p>
<h4 id="ajouter-un-nœud">Ajouter un nœud</h4>
<p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># server name</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[srvr.huc.fr.eu.org]</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># address IP</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">address 192.168.1.1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">use_node_name yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># first pc</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[pc1.huc.fr.eu.org]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">address 192.168.1.10</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">use_node_name yes</span>
</span></span></code></pre></div><h4 id="recevoir-les-alertes-par-mail">Recevoir les alertes par mail</h4>
<p>Pour recevoir les alertes par mail, il est nécessaire de renseigner une ou
plusieurs adresses de contact, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">contact.root.command mail -s &#34;Munin notification&#34; email</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">contact.other-user.command mail -s &#34;Munin notification&#34; email-user</span>
</span></span></code></pre></div><p>Ceci étant un exemple, remplacez par les informations nécessaires à votre
situation.</p>
<h3 id="munin-nodeconf">munin-node.conf</h3>
<p>La partie de la <a class="inside" href="/fr/sys/openbsd/munin-node/" title="Lien interne vers l&#39;article : ''">configuration du fichier de nœud</a>

étant expliquée sur sa propre page, il suffit de suivre les informations et de
les adapter au nœud du serveur lui-même.</p>
<h3 id="crontab">crontab</h3>
<p>Après avoir configuré les deux fichiers de configuration ci-dessus, il est
important de paramétrer une tâche cron, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># crontab for munin-server</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">*/5     *       *       *       *       su  -s /bin/sh _munin /usr/local/bin/munin-cron</span>
</span></span></code></pre></div><h3 id="newsyslogconf">newsyslog.conf</h3>
<p>Il est nécessaire de modifier le fichier de configuration du journal
<code>/etc/newsyslog.conf</code> pour créer une rotation des journaux générés par munin.</p>
<p>Ajoutez-y :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># munin-server</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-cgi-graph.log  www:_munin  644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-cgi-html.log   www:_munin  644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-graph.log  _munin:_munin   644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-html.log   _munin:_munin   644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-limits.log _munin:_munin   644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/www/logs/munin/munin-update.log _munin:_munin   644  7     250  *     Z</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># munin-node</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/var/log/munin/munin-node.log   root:wheel      644  7     250  *     Z</span>
</span></span></code></pre></div><p>Ce sont tous les journaux gérés et nécessaires à minima pour munin.</p>
<h3 id="httpd">httpd</h3>
<p>Ici, je vous renvoie à mon article de découverte du serveur <strong>httpd</strong>, et tout
particulièrement aux informations d'
<a class="inside" href="/fr/web/httpd/httpd/#utilisation" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">utilisations</a>
.</p>
<p>Modification du fichier de configuration <code>/etc/httpd.conf</code> pour y ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">include &#34;/etc/httpd.d/munin.conf&#34;</span>
</span></span></code></pre></div><p>Création du fichier de config du serveur pour nagios <code>/etc/httpd.d/munin.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server &#34;192.168.1.3&#34; {</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on * port 80</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">root &#34;/htdocs/munin&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#    location &#34;/cgi-bin/munin-cgi*&#34; {</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#        fastcgi socket &#34;/run/slowcgi.sock&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#        root &#34;/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#    }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">directory index index.html</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Les fichiers dans le répertoire web de munin doivent avoir les droits de
l&rsquo;utilisateur <code>_munin</code> et du groupe web <code>www</code>, par défaut.</p>
<h4 id="chroot-web">Chroot web</h4>
<p>Du fait du chroot web, il est nécessaire de faire les modifications systèmes suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# mkdir -p /var/www/<span style="color:#5bc4bf">{</span>logs,var/run<span style="color:#5bc4bf">}</span>/munin
</span></span><span style="display:flex;"><span>:# chown _munin: /var/www/<span style="color:#5bc4bf">{</span>logs,var/run<span style="color:#5bc4bf">}</span>/munin
</span></span></code></pre></div><p>mais en plus de modifier la <a href="/fr/monitor/openbsd-munin-server/#munin.conf">configuration du fichier du serveur</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">htmldir /var/www/htdocs/munin</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">logdir /var/www/logs/munin</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rundir  /var/www/var/run/munin</span>
</span></span></code></pre></div><h3 id="packet-filter">Packet-Filter</h3>
<p>Concernant les règles pour 







































































<span lang="en">PF <em>(Packet Filter)</em></span>







































, il faut ouvrir en entrée et sortie,
vers et depuis les nœuds :</p>
<ul>
<li>pour Munin lui-même : <code>4949/tcp</code></li>
<li>pour SNMP : <code>161</code>, <code>162</code> en <code>udp</code> et <code>tcp</code> - cela dépend de votre configuration
<a class="tag" href="/fr/tags/snmp">SNMP</a>
, bien sûr.</li>
</ul>
<h2 id="démarrage-des-services">Démarrage des services</h2>
<p>Pensez à activer et démarrer les services nécessaires, si ce n&rsquo;est pas fait !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# rcctl enable munin_node munin_asyncd slowcgi httpd
</span></span><span style="display:flex;"><span>:# rcctl start munin_node munin_asyncd slowcgi
</span></span><span style="display:flex;"><span>:# httpd -n <span style="color:#5bc4bf">&amp;&amp;</span> rcctl start httpd
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<h3 id="erreur--failed-to-create-rundir-varrunmunin-permission-denied">Erreur : Failed to create rundir (/var/run/munin): Permission denied</h3>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            Failed to create rundir (/var/run/munin): Permission denied at /usr/local/libexec/munin/munin-update line 39.
        </blockquote>
    </figure>
</div>

<ul>
<li>Avez-vous réellement fait lu le chapitre <strong><a href="/fr/monitor/openbsd-munin-server/#chroot-web">chroot</a></strong> ?</li>
</ul>
<h3 id="erreur--fatal-there-is-nothing-to-do-here-since-there-are-no-nodes-with-any-plugins">Erreur : [FATAL] There is nothing to do here, since there are no nodes with any plugins</h3>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            [FATAL] There is nothing to do here, since there are no nodes with any plugins.  Please refer to <a href="http://munin-monitoring.org/wiki/FAQ_no_graphs" rel="external">http://munin-monitoring.org/wiki/FAQ_no_graphs</a> at /usr/local/libexec/munin/munin-html line 40.
        </blockquote>
    </figure>
</div>

<ul>
<li>
<p>Avez-vous démarré vos services munin ?</p>
</li>
<li>
<p>Avez-vous activé/désactivé des plugins ? Si oui, avez vous redémarré le
service <code>munin-node</code> ?</p>
</li>
</ul>
<hr>
<h2 id="remerciements">Remerciements</h2>
<p>Une spéciale dédicace à <a href="http://solene.perso.pw" rel="external">Solene Rapenne</a> qui fait partie
de l&rsquo;équipe d&rsquo;OpenBSD, et qui m&rsquo;a bien aider pour démarrer ce projet.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place Munin pour monitorer, faire de la métrologie, surveiller du matériel informatique, sous OpenBSD, fonctionnant en relation avec le service web httpd]]></summary>
        <published>2019-11-16T23:18:30+01:00</published>
        <updated>2019-11-22T20:00:00+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a5173605-f648-c1f5-16c4-738d57782f27</id>
        <link href="http://doc.huc.fr.eu.org/fr/monitor/openbsd-nagios/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nagios : Monitorer OpenBSD avec httpd &#43; slowcgi</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="httpd" scheme="http://doc.huc.fr.eu.org/fr/tags/httpd/" />
        <category term="nagios" scheme="http://doc.huc.fr.eu.org/fr/tags/nagios/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="slowcgi" scheme="http://doc.huc.fr.eu.org/fr/tags/slowcgi/" />
        <category term="serveur" scheme="http://doc.huc.fr.eu.org/fr/tags/serveur/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Nagios est un moniteur d&rsquo;hôtes et de services conçu pour vous informer sur vos
machines clientes, utilisateurs finaux ou gestionnaires.</p>
<p>Le démon de surveillance exécute des contrôles intermittents sur les hôtes et
les services que vous spécifiez à l&rsquo;aide de &ldquo;plugins&rdquo; externes qui retournent
les informations d&rsquo;état à Nagios. En cas de problèmes, le démon peut envoyer à
des contacts administratifs dans une variété de pays différents par différents
biais (courriel, messagerie instantanée, SMS, etc.) des informations sur l&rsquo;état
actuel ; les rapports peuvent tous être consultés par l&rsquo;intermédiaire d&rsquo;un
navigateur Web.</p>
<ul>
<li>Site web : <a href="https://www.nagios.org/projects/" rel="external">https://www.nagios.org/projects/</a></li>
<li>Version : 4.3.1</li>
<li>OpenBSD : 6.6</li>
<li>Services : httpd + slowcgi + nagios + php73_fpm</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>Il est toujours utile de lire les documentations <code>pkg-readmes</code> fournies ;
celles disponibles sont dans <code>/usr/local/share/doc/pkg-readmes/</code>, à-propos de :</p>
<ul>
<li>femail-chroot</li>
<li>nagios</li>
<li>php-7.3</li>
</ul>
<h2 id="installation-du-serveur-nagios">Installation du serveur Nagios</h2>
<p>Afin de fonctionner avec le serveur web natif à OpenBSD, dixit 
<a class="man" href="https://man.openbsd.org/httpd.8" title="Page du Manuel OpenBSD pour : httpd">httpd(8)</a>
,
installez les paquets <code>nagios-*-chroot</code> spécifiques pour l&rsquo;usage avec ce
serveur web natif :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# pkg_add nagios-4.3.1p1-chroot nagios-web-4.3.1p2-chroot
</span></span><span style="display:flex;"><span>quirks-3.182 signed on 2019-11-15T10:35:39Z
</span></span><span style="display:flex;"><span>nagios-4.3.1p1-chroot:libltdl-2.4.2p1: ok
</span></span><span style="display:flex;"><span>nagios-4.3.1p1-chroot:monitoring-plugins-2.2p8: ok
</span></span><span style="display:flex;"><span>useradd: Warning: home directory <span style="color:#48b685">`</span>/var/www/nagios<span style="color:#48b685">&#39; doesn&#39;</span>t exist, and -m was not specified
</span></span><span style="display:flex;"><span>nagios-4.3.1p1-chroot: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot:femail-1.0p1: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot:femail-chroot-1.0p3: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot:argon2-20171227: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot:php-7.3.11: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot:php-gd-7.3.11: ok
</span></span><span style="display:flex;"><span>nagios-web-4.3.1p2-chroot: ok
</span></span><span style="display:flex;"><span>The following new rcscripts were installed: /etc/rc.d/nagios /etc/rc.d/php73_fpm
</span></span><span style="display:flex;"><span>See rcctl<span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> <span style="color:#815ba4">for</span> details.
</span></span><span style="display:flex;"><span>New and changed readme<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>    /usr/local/share/doc/pkg-readmes/femail-chroot
</span></span><span style="display:flex;"><span>    /usr/local/share/doc/pkg-readmes/nagios
</span></span><span style="display:flex;"><span>    /usr/local/share/doc/pkg-readmes/php-7.3
</span></span></code></pre></div><p>Le répertoire web par défaut est <code>/var/www/nagios</code> ; des scripts CGI sont installés dans <code>/var/www/cgi-gin/nagios/</code>.</p>
<h3 id="femail-chroot">Femail-chroot</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# cd /var/www/
</span></span><span style="display:flex;"><span>:# mkdir -p etc/ssl
</span></span><span style="display:flex;"><span>:# cp /etc/<span style="color:#5bc4bf">{</span>resolv.conf,hosts,localtime<span style="color:#5bc4bf">}</span> etc/
</span></span><span style="display:flex;"><span>:# install -m <span style="color:#f99b15">444</span> -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl
</span></span><span style="display:flex;"><span>:# chmod -R <span style="color:#f99b15">444</span> etc/*
</span></span><span style="display:flex;"><span>:# chmod -R a+X etc/
</span></span><span style="display:flex;"><span>:# cp /bin/sh /var/www/bin/
</span></span></code></pre></div><h3 id="test-config-nagios">Test config nagios</h3>
<p>La commande de test de la configuration de nagios est :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ su -m _nagios -c <span style="color:#48b685">&#34;/usr/local/sbin/nagios -v /etc/nagios/nagios.cfg&#34;</span>
</span></span></code></pre></div><p>Exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ su -m _nagios -c <span style="color:#48b685">&#34;/usr/local/sbin/nagios -v /etc/nagios/nagios.cfg&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Nagios Core 4.3.1
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 2009-present Nagios Core Development Team and Community Contributors
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1999-2009 Ethan Galstad
</span></span><span style="display:flex;"><span>Last Modified: 02-23-2017
</span></span><span style="display:flex;"><span>License: GPL
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Website: https://www.nagios.org
</span></span><span style="display:flex;"><span>Reading configuration data...
</span></span><span style="display:flex;"><span>   Read main config file okay...
</span></span><span style="display:flex;"><span>   Read object config files okay...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Running pre-flight check on configuration data...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Checking objects...
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">8</span> services.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">1</span> hosts.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">1</span> host groups.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">0</span> service groups.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">1</span> contacts.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">1</span> contact groups.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">24</span> commands.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">5</span> time periods.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">0</span> host escalations.
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">0</span> service escalations.
</span></span><span style="display:flex;"><span>Checking <span style="color:#815ba4">for</span> circular paths...
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">1</span> hosts
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">0</span> service dependencies
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">0</span> host dependencies
</span></span><span style="display:flex;"><span>    Checked <span style="color:#f99b15">5</span> timeperiods
</span></span><span style="display:flex;"><span>Checking global event handlers...
</span></span><span style="display:flex;"><span>Checking obsessive compulsive processor commands...
</span></span><span style="display:flex;"><span>Checking misc settings...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Total Warnings: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>Total Errors:   <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Things look okay - No serious problems were detected during the pre-flight check
</span></span></code></pre></div><p>Ensuite, penser à activer et démarrer le service <code>nagios</code> avec le contrôleur

<a class="man" href="https://man.openbsd.org/rcctl.8" title="Page du Manuel OpenBSD pour : rcctl">rcctl(8)</a>
.</p>
<h3 id="php-fpm">PHP-FPM</h3>
<ul>
<li>Le service se nomme : <code>php73_fpm</code></li>
<li>L&rsquo;outil pour tester la configuration est : <code>php-fpm-73</code> avec l&rsquo;option <code>-t</code>,
par exemple.</li>
</ul>
<h4 id="httpd-configuration">httpd configuration</h4>
<p>Le <a class="inside" href="/fr/web/httpd/httpd/#php-fpm" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">fragment de configuration</a>

pour <code>httpd</code> nécessaire est expliqué dans mon article présentant httpd.</p>
<h4 id="activer-les-modules">Activer les modules</h4>
<p>Les commandes suivantes sont à exécuter à chaque installation d&rsquo;un module PHP,
pecl, et opcache :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# cd /etc/php-7.3.sample
</span></span><span style="display:flex;"><span>:# <span style="color:#815ba4">for</span> i in *; <span style="color:#815ba4">do</span> ln -sf ../php-7.3.sample/<span style="color:#ef6155">$i</span> ../php-7.3/; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><h4 id="openssl-functions">OpenSSL Functions</h4>
<p>Du fait de la prison <code>/var/www</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# mkdir -p /var/www/etc/ssl
</span></span><span style="display:flex;"><span>:# install -m <span style="color:#f99b15">444</span> -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl/
</span></span></code></pre></div><h3 id="slowcgi">slowcgi</h3>
<ul>
<li>Le service se nomme tout simplement : <code>slowcgi</code>.</li>
<li>Les scripts cgi fournis dans <code>/var/www/cgi-bin/</code> sont accessibles grâce à

    <a class="man" href="https://man.openbsd.org/slowcgi.8" title="Page du Manuel OpenBSD pour : slowcgi">slowcgi(8)</a>
. <br>
Ceux de nagios sont fournis dans le répertoire enfant <code>nagios/</code>.</li>
</ul>
<h3 id="httpd">httpd</h3>
<p>Ici, je vous renvoie à mon article de découverte du serveur <strong>httpd</strong>, et tout
particulièrement aux informations d'
<a class="inside" href="/fr/web/httpd/httpd/#utilisation" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">utilisations</a>
.</p>
<p>Modification du fichier de configuration <code>/etc/httpd.conf</code> pour y ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">include &#34;/etc/httpd.d/nagios.conf&#34;</span>
</span></span></code></pre></div><p>Création du fichier de config du serveur pour nagios <code>/etc/httpd.d/nagios.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">server &#34;192.168.1.3&#34; {</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">listen on * port 80</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">root &#34;/&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/cgi-bin/nagios/*.cgi&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">authenticate &#34;! Nagios Restricted !&#34; with &#34;/nagios.ht&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">fastcgi socket &#34;/run/slowcgi.sock&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;/&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">authenticate &#34;! Nagios Restricted !&#34; with &#34;/nagios.ht&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">directory index index.php</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/nagios&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">location &#34;*.php&#34; {</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">fastcgi socket &#34;/run/php-fpm.sock&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">root &#34;/nagios&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p><span class="IMP">Il est hautement recommandé de créer une authentification web
avec accès restreint !</span></p>
<h4 id="création-de-lauthentification-web">Création de l&rsquo;authentification web</h4>
<p>Sachant que le compte admin par défaut est <code>nagiosadmin</code>, utilisons l&rsquo;outil
<a class="inside" href="/fr/web/httpd/httpd/#authentification-web" title="Lien interne vers l&#39;article : 'httpd : présentation du serveur HTTP d&#39;OpenBSD'">htpasswd</a>
 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# htpasswd nagios.ht nagiosadmin
</span></span></code></pre></div><p><span class="IMP">Réfléchissez bien avant de vouloir changer de nom
d&rsquo;administrateur, car il faudra le modifier au moins dans le fichier
<code>objects/contacts.cfg</code>…</span></p>
<p>Ensuite, il faut lui donner des droits d&rsquo;exécution <code>0400</code>, et utilisateur web
<code>www</code>, autrement l&rsquo;authentification ne se fera pas.</p>
<p><em>Il est ensuite possible de configurer d&rsquo;autres utlisateurs, de la même manière
auquels un rôle sera attribué, tel que celui d&rsquo;<code>operator</code></em>.</p>
<h2 id="configuration">Configuration</h2>
<p>Tous les fichiers de configuration se trouvent dans <code>/etc/nagios</code> - <em>qui se
trouve être un alias de <code>/var/www/etc/nagios</code> </em> :</p>
<h3 id="cgicfg">cgi.cfg</h3>
<ul>
<li>
<p>Option <code>use_authentication</code> : <br>
<span class="IMP">Seulement le temps de tester que tout fonctionne, il est
possible de mettre la valeur à <code>O</code> pour désactiver l&rsquo;authentification</span> <br>
<span class="red">ATTENTION, c'est une très mauvaise idée de fonctionner
    sans authentification !</span>
</p>
</li>
<li>
<p>Les options <code>authorized_for_*</code> : si vous avez paramétré un rôle particulier,
ou tout autre nom d&rsquo;utilisateur, vous pouvez l&rsquo;ajouter selon ce qui est
désirable d&rsquo;être utilisé par ce rôle, ou cet utilisateur.</p>
</li>
<li>
<p>Option <code>show_context_help</code> : utile pour avoir une aide contextuelle</p>
</li>
<li>
<p>Il peut être intéressant de configurer les options <code>*_sound</code> qui émettront un
son caractéristique lié à l&rsquo;erreur remontée.</p>
</li>
<li>
<p>Laissez l&rsquo;option <code>lock_author_names</code> sur la valeur <code>1</code> permet d&rsquo;empêcher le
changement de nom d&rsquo;utilisateur.</p>
</li>
</ul>
<h3 id="nagioscfg">nagios.cfg</h3>
<ul>
<li>Option <code>admin_email</code> : remplacer la valeur par défaut, par votre courriel.</li>
<li>Option <code>date_format</code> : choisir la valeur <code>euro</code></li>
<li>Option <code>use_timezone</code> : paramètrer <code>Europe/Paris</code></li>
</ul>
<p>Les fichiers de configuration se trouvent dans le répertoire enfant <code>objects</code> :</p>
<h3 id="contactscfg">contacts.cfg</h3>
<ul>
<li>Définition <code>alias</code> : remplacer par un alias d&rsquo;administration personnalisé, si besoin.</li>
<li>Définition <code>contact_name</code> : remplacer par votre identifiant</li>
<li>Définition <code>email</code> : remplacer par votre courriel administrateur</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="erreur--not-have-permission-to-view">Erreur : not have permission to view</h3>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            <span class="red">It appears as though you do not have permission to view information for any of the hosts you requested…</span><br>
<br>
If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI and check the authorization options in your CGI configuration file.
        </blockquote>
    </figure>
</div>

<ul>
<li>
<p>Êtes-vous sûr d&rsquo;avoir créé un utilisateur qui a/aura les droits de regarder
la vue en question ?</p>
</li>
<li>
<p>Si oui, êtes-vous sûr d&rsquo;avoir autorisé l&rsquo;utilisateur dans les fichiers de
configuration, tel celui de <code>cgi.cfg</code>, cf les options <code>authorized_*</code> ?</p>
</li>
<li>
<p>Si oui, êtes-vous sûr d&rsquo;avoir relancé les différents services, tel httpd ou
nagios ?</p>
</li>
</ul>
<p><span class="error">Cherchez votre oubli !</span></p>
<hr>
<p>Autres moniteurs réseaux :</p>
<ul>
<li>Icinga2</li>
<li>LibreNMS : <a href="https://www.librenms.org" rel="external">https://www.librenms.org</a></li>
<li>Zabbix : <a href="https://www.zabbix.com" rel="external">https://www.zabbix.com</a></li>
</ul>
]]></content>
        <summary type="html"><![CDATA[Comment mettre en place Nagios, sous OpenBSD, couplé avec les services web httpd et CGI slowcGI pour assurer le monitoring du matériel informatique. ]]></summary>
        <published>2019-11-14T10:56:30+01:00</published>
        <updated>2019-11-17T06:05:06+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:91ab9e09-6243-7f68-4a02-854d55a35531</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-icmp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer le protocole ICMP</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="ICMP" scheme="http://doc.huc.fr.eu.org/fr/tags/icmp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Cet article peut très bien être utile pour le PF embarqué dans <a href="https://wiki.debian.org/fr/Debian_GNU/kFreeBSD" rel="external">Debian GNU/kFreeBSD</a> !</div>

<p>Suivant les recommandations que l&rsquo;on retrouve sur mon autre 
<a class="inside" href="/fr/sec/firewall/linux-firewall-icmp/" title="Lien interne vers l&#39;article : 'Linux : firewall ICMP'">article</a>
,
à-propos des règles à mettre en place pour autoriser ou bloquer le flux
ICMP, voici les règles PF adéquates, pour tout BSD qui utilise Packet Filter,
dont OpenBSD :</p>
<h2 id="gestion">Gestion</h2>
<h3 id="les-codes-icmp-à-rejeter">Les codes ICMP à rejeter</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">icmp_block_types</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{ 4 6 15 16 17 18 31 32 33 34 35 36 37 38 39 }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>block drop quick on egress inet proto icmp icmp-type <span style="color:#f99b15">3</span> code <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>block drop in quick on egress inet proto icmp icmp-type <span style="color:#f99b15">3</span> code <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>block drop quick on egress inet proto icmp icmp-type <span style="color:#f99b15">3</span> code <span style="color:#f99b15">8</span>
</span></span><span style="display:flex;"><span>block drop quick on egress inet proto icmp icmp-type <span style="color:#ef6155">$icmp_block_types</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il semble que PF ne comprend pas les options <strong>37</strong>,
<strong>38</strong> <em>(respectivement <strong>Domain Name Request</strong>, et <strong>Domain Name Reply</strong>)</em> ;
du moins, il ne les traduit pas, comme il le fait très bien avec les autres options !</div>

<h3 id="les-codes-icmp-à-autoriser">Les codes ICMP à autoriser</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">L&rsquo;équivalent <code>limit</code> d&rsquo;Iptables n&rsquo;existe pas pour PF !<br>
Il semble que c&rsquo;est géré finement par le noyau BSD d&rsquo;OpenBSD.</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">icmp_types</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;{ 8 11 12 }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>block log
</span></span><span style="display:flex;"><span>pass out
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pass in quick on egress inet proto icmp from any to egress icmp-type <span style="color:#5bc4bf">{</span> <span style="color:#f99b15">3</span> code 3, <span style="color:#f99b15">3</span> code <span style="color:#f99b15">4</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>pass in quick on egress inet proto icmp from any to egress icmp-type <span style="color:#ef6155">$icmp_types</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pass out quick on egress inet proto icmp from egress to any icmp-type <span style="color:#5bc4bf">{</span> <span style="color:#f99b15">3</span> code 3, <span style="color:#f99b15">3</span> code <span style="color:#f99b15">4</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>pass out quick on egress inet proto icmp from egress to any icmp-type <span style="color:#ef6155">$icmp_types</span>
</span></span></code></pre></div><p>Bien-sûr, vous pouvez autoriser tous les autres codes qui peuvent être autorisés
et dont les recommandations sont de limiter. Les trois codes mis en exergue sont un minima !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer le protocole ICMP avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f89c68fa-753e-d557-40ae-6b3a8655b277</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-icmpv6/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gérer le protocole ICMPv6</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="ICMPv6" scheme="http://doc.huc.fr.eu.org/fr/tags/icmpv6/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Cet article peut très bien être utile pour le PF embarqué dans
<a href="https://wiki.debian.org/fr/Debian_GNU/kFreeBSD" rel="external">Debian GNU/kFreeBSD</a> !</div>

<p>Reprenant le principe des informations renfermées dans mon autre

<a class="inside" href="/fr/sec/firewall/linux-firewall-icmpv6/" title="Lien interne vers l&#39;article : 'Linux : firewall ICMPv6'">article</a>
,
à-propos des recommandations faites pour autoriser ou bloquer le flux
ICMPv6, voici les règles PF adéquates pour tout BSD qui utilise
Packet Filter, dont OpenBSD :</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ne JAMAIS oublier que toute la pile IPv6, à la différence d&rsquo;IPv4, se repose
vraiment sur ICMPv6 ; ainsi, une mauvaise configuration d&rsquo;ICMPv6 empêchera
assurément tout ou partie du flux IPv6 de fonctionner correctement, ou
comme attendu !</div>

<h2 id="gestion">Gestion</h2>
<h3 id="les-codes-icmp-à-rejeter">Les codes ICMP à rejeter</h3>
<p>Ces types ICMPv6 sont à rejeter absolument :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_block</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 100 101 127 138 139 140 144 145 146 147 150 200 201 }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop quick log on egress inet6 proto icmp6 icmp6-type $icmp6_block</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>ATTENTION</strong> : Concernant les types 144 à 147, ce sont les messages qui
servent à la mobilité d&rsquo;un nœud (tel qu&rsquo;une tablette, un laptop, etc…) ;
dans ce contexte, il est nécessaire de ne pas les supprimer.</div>

<hr>
<h3 id="les-codes-icmpv6-à-autoriser">Les codes ICMPv6 à autoriser</h3>
<p>⇒ Gestion d&rsquo;une station :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_auth</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto icmp6 from any       to ff02::2 icmp6-type { routersol, listenrepv2 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass     quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>
<p>La première règle définit les types ICMPv6 autorisés nécessaires,
au minimum.</p>
</li>
<li>
<p>La deuxième règle autorise en sortie :</p>
<ul>
<li>les sollicitations depuis notre station à destination d&rsquo;un routeur
— <code>ff02::2</code> est l&rsquo;adresse multicast local de tout routeur —</li>
<li>ainsi que les messages &ldquo;Multicast Listener Report Message v2&rdquo;
<code>listenrepv2</code></li>
<li>ces deux types ICMPv6 sont nécessaires pour communiquer localement</li>
<li>cette règle est placée en premier car il faut bien que la station
annonce qu&rsquo;elle a besoin d&rsquo;une adresse routable.</li>
</ul>
</li>
<li>
<p>La troisième règle autorise en entrée les annonces de routeur — type 143 —
à destination du nœud local de notre station — <code>ff02::1</code>.</p>
<ul>
<li>c&rsquo;est la réponse du routeur vers la requête précédente de notre
station</li>
</ul>
</li>
<li>
<p>La quatrième règle autorise en entrée et en sortie, tous les types
mentionnés dans la première règle — la macro <code>$icmp6_auth</code>.</p>
</li>
<li>
<p>La cinquième règle autorise en entrée toute annonce ICMPv6 de
redirection vers une route plus courte.</p>
</li>
</ul>
<p>Les règles deux et trois sont strictement nécessaires pour débuter une
communication sur le protocole IPv6 ; sans elles, la station sera
incapable de le faire correctement !</p>
<hr>
<p>⇒ Gestion d&rsquo;un routeur :</p>
<p>Pour débuter, faisons simplement :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_auth</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ echoreq echoreq neighbradv neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto icmp6 icmp6-type routeradv</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass     quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth</span>
</span></span></code></pre></div><h4 id="limiter-le-trafic">Limiter le trafic</h4>
<p>Pour limiter le trafic ICMPv6, PF peut utiliser les
<abbr title="Stateful Tracking Options">STO</abbr>
.</p>
<p>Pour reprendre l&rsquo;exemple ci-dessus, en utilisant l&rsquo;option
<code>max-src-conn-rate</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_auth</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ unreach toobig timex paramprob echoreq neighbradv neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_sto</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;( max-src-conn-rate 100/10 )&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto icmp6 from any       to ff02::2 icmp6-type { routersol, listenrepv2 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass     quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts $icmp6_sto</span>
</span></span></code></pre></div><h4 id="autorisations-plus-restrictives">Autorisations plus restrictives</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_auth</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ unreach, toobig, timex code 0, timex code 1, paramprob code 1, paramprob code 2, echorep, echoreq, neighbradv, neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_out</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ echorep, echoreq, neighbradv, neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_sto</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;( max-src-conn-rate 100/10 )&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto icmp6 from any       to ff02::2 icmp6-type { routersol, listenrepv2 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv, redir }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass     quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto from egress to any icmp6 icmp6-type $icmp6_out allow-opts $icmp6_sto</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>
<p>La règle <code>icmp6_auth</code> ne gére que ce qui est absolument nécessaire…
<strong>attention à bien utiliser les virgules séparant les codes,
autrement elle ne serait pas fonctionnelle</strong> !</p>
</li>
<li>
<p>La règle <code>icmp6_out</code> n&rsquo;autorise seulement que les messages d&rsquo;echo et
les messages de découvertes des voisins.</p>
</li>
<li>
<p>on a ajouté dans la première règle <code>in</code> la gestion des messages de
redirection vers une route plus courte, seulement depuis un routeur
vers notre machine. <strong>ATTENTION</strong> : autoriser le message de redirection
de toute autre manière posera des problèmes de sécurité, à tel point
qu&rsquo;il semble recommander de les supprimer dans le contexte de parefeu !</p>
</li>
</ul>
<hr>
<p>⇒ Cas d&rsquo;un routeur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_auth</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">icmp6_sto</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;( max-src-conn-rate 100/10 )&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in  quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet6 proto icmp6 icmp6-type { routeradv, redir }</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass     quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto</span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<ul>
<li><a href="http://livre.g6.asso.fr/index.php/Lien-local" rel="external">http://livre.g6.asso.fr/index.php/Lien-local</a></li>
<li><a href="https://www.openbsd.org/faq/pf/filter.html#stateopts" rel="external">Stateful Tracking Options</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gérer le protocole ICMPv6 avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:462c7508-287c-9fc0-eb84-90b18a91d1fb</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-traceroute/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les connexions de l&#39;outil traceroute</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="traceroute" scheme="http://doc.huc.fr.eu.org/fr/tags/traceroute/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La commande <code>traceroute</code> a un comportement particulier, car il est possible
d&rsquo;utiliser l&rsquo;option <code>-I</code> afin de simuler le comportement d&rsquo;ICMP, voire d&rsquo;ICMPv6.</p>
<p>Voici la règle utile afin de sortir sur le protocol <code>udp</code> :</p>
<p><code>pass out on egress inet proto udp to port 33433:33626</code></p>
<p>La commande équivalente nommée <code>traceroute6</code> pour la pile IPv6 fonctionne
avec les mêmes options, donc de la même manière !</p>
<h2 id="documentation">Documentation</h2>
<h3 id="manpage">Manpage</h3>
<p>Allez lire un peu le manpage <a href="https://man.openbsd.org/traceroute.8" rel="external">traceroute(8)</a>,
cela fait toujours du bien de se rafraîchir la mémoire !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions de l&#39;outil traceroute avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b283ad20-2310-d52e-ed57-ae44b1c46620</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-saned/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les connexions du scanner logiciel saned</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="saned" scheme="http://doc.huc.fr.eu.org/fr/tags/saned/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Normalement le port donné pour le service <code>sane</code> est le <code>6566</code> sur le protocole <code>tcp</code>.</p>
<p>Il suffit donc d&rsquo;écrire une règle équivalente :</p>
<p><code>pass out on egress proto tcp from egress to egress:network port 6566 flag S/SA modulate state</code></p>
<hr>
<h3 id="cas-dune-imprimante-mfp-epson">Cas d&rsquo;une imprimante MFP Epson</h3>
<p>Si vous avez une MFP de marque Epson, le port <code>1865</code> sur <code>udp</code> est celui qu&rsquo;il
faut contacter…
par défaut. <em>(d&rsquo;autres sont possibles, dépendant de votre modèle)</em></p>
<p>Mais une analyse de l&rsquo;activité sur l&rsquo;interface <code>pflog0</code>, par le biais de
la fameuse commande <code>tcpdump -n -e -ttt -i pflog0</code> nous restitue qu&rsquo;il
envoie des paquets sur <code>udp</code> à l&rsquo;attention du réseau local, puis interroge
en envoyant des paquets broadcasts, avant d&rsquo;obtenir une réponse de l&rsquo;imprimante… <br>
bref, tout se passe en <code>udp</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:25.146815 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.8612 &gt; 192.168.1.255.8612: udp <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:25.146890 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.8612 &gt; 192.168.1.255.8610: udp <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:25.158437 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.8612 &gt; 192.168.1.255.8612: udp <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:25.158493 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.8612 &gt; 192.168.1.255.8610: udp <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:30.007313 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.4891 &gt; 255.255.255.255.3289: udp <span style="color:#f99b15">15</span> <span style="color:#5bc4bf">[</span>ttl 1<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:30.020862 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.3.3289 &gt; 192.168.1.2.4891: udp <span style="color:#f99b15">76</span>
</span></span><span style="display:flex;"><span>Oct <span style="color:#f99b15">10</span> 13:15:31.171140 rule 53/<span style="color:#5bc4bf">(</span>match<span style="color:#5bc4bf">)</span> block in on axe0: 192.168.1.2.17068 &gt; 255.255.255.255.1124: udp <span style="color:#f99b15">37</span> <span style="color:#5bc4bf">[</span>ttl 1<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><p>Le plus simple est d&rsquo;autoriser le flux du protocole <code>udp</code> entrant et
venant du réseau local vers ou depuis l&rsquo;interface locale :</p>
<pre tabindex="0"><code>pass in quick on egress proto udp from egress to egress:network allow-opts
pass in quick on egress proto udp from egress:network to egress allow-opts
</code></pre><hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions du logiciel de scanner saned avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:07bf5cba-e134-ea61-f822-8e8b35f5202f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-avahi/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les connexions du service avahi</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="avahi" scheme="http://doc.huc.fr.eu.org/fr/tags/avahi/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici les règles pare-feu au besoin :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># avahi</span>
</span></span><span style="display:flex;"><span>pass on egress inet proto udp from any to 224.0.0.251 port mdns allow-opts
</span></span><span style="display:flex;"><span>pass on egress inet6 proto udp from any to ff02::fb port mdns allow-opts
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ssdp</span>
</span></span><span style="display:flex;"><span>pass on egress inet proto udp from any to 239.255.255.250 port <span style="color:#f99b15">1900</span> allow-opts
</span></span><span style="display:flex;"><span>pass on egress inet6 proto udp from any to <span style="color:#5bc4bf">{</span> ff02::c, ff05::c, ff08::c <span style="color:#5bc4bf">}</span> port <span style="color:#f99b15">1900</span> allow-opts
</span></span></code></pre></div><h3 id="précisions">Précisions</h3>
<p>Concernant le trafic SSDP :</p>
<ul>
<li>pour IPv6 :
<ul>
<li><code>ff02::c</code> est l&rsquo;adresse multicast de lien local</li>
<li><code>ff05::c</code> est l&rsquo;adresse multicast de site local</li>
<li><code>ff08::c</code> est l&rsquo;adresse multicast d&rsquo;organisation local</li>
<li>il existe aussi <code>ff0e::c</code> pour l&rsquo;adresse multicast global - que nous
n&rsquo;utiliserons pas dans le contexte local !</li>
</ul>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions avahi avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:50280c20-3fe8-4e72-55ae-0f0eb38225fe</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-samba/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les connexions du service Samba</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="SMB" scheme="http://doc.huc.fr.eu.org/fr/tags/smb/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici les règles PF nécessaires :</p>
<p>⇒ macros</p>
<pre tabindex="0"><code>smb_ports_tcp = &#34;{ 135 137 139 445 }&#34;
smb_ports_udp = &#34;{ 135 137 138 445 }&#34;
</code></pre><p>⇒ samba in</p>
<pre tabindex="0"><code>pass in quick on egress proto tcp from egress:network to egress port $smb_ports_tcp flags S/SA modulate state
pass in quick on egress proto udp from egress:network to egress port $smb_ports_udp allow-opts
</code></pre><p>⇒ samba out</p>
<pre tabindex="0"><code>pass out on egress proto tcp from egress to egress:network port $smb_ports_tcp flags S/SA modulate state
pass out on egress proto udp from egress to egress:network port $smb_ports_udp allow-opts
</code></pre><hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gérer les connexions du service SMB avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:efed9fc4-9c79-e5dd-79c0-579231f67909</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-syncthing/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les connexions du service Syncthing</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="syncthing" scheme="http://doc.huc.fr.eu.org/fr/tags/syncthing/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici les règles PF nécessaires :</p>
<p>⇒ in :</p>
<pre tabindex="0"><code>pass in quick on egress inet proto tcp from egress:network to egress port 22000 flags S/SA modulate state
pass in quick on egress inet proto udp from egress:network to egress port 21027 allow-opts
</code></pre><p>⇒ out :</p>
<pre tabindex="0"><code>pass out quick on egress inet proto tcp from egress to egress:network port 22000 flags S/SA modulate state
pass out quick on egress inet proto udp from egress to egress:network port 21027 allow-opts
</code></pre><p>Bien-sûr, ces règles pour Syncthing sont à modifier, surtout si vous modifiez les ports dans la configuration de Syncthing !</p>
<p>Ce sont des règles de bases, pour exemple !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions du service Syncthing avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:38d6f0ab-ee6b-f6df-23f2-54f406ee3b46</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/pf-ping/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PF accepte de gèrer les ping</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="PF" scheme="http://doc.huc.fr.eu.org/fr/tags/pf/" />
        <category term="Packet-Filter" scheme="http://doc.huc.fr.eu.org/fr/tags/packet-filter/" />
        <category term="ping" scheme="http://doc.huc.fr.eu.org/fr/tags/ping/" />
        <category term="ICMP" scheme="http://doc.huc.fr.eu.org/fr/tags/icmp/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Très simplement :</p>
<p>⇒ IPv4 :</p>
<p><code>pass on egress inet proto icmp all icmp-type echoreq</code></p>
<p>⇒ IPv6 :</p>
<p><code>pass on egress inet6 proto icmp all icmp6-type echoreq</code></p>
<h2 id="documentation">Documentation</h2>
<h3 id="manpage">Manpage</h3>
<p>N&rsquo;hésitez pas à (re?)lire le manpage concernant la commande
<a href="https://man.openbsd.org/ping.8" rel="external"><code>ping</code></a>,
et son équivalent <code>ping6</code> qui fonctionne de la même manière avec presque
toutes les mêmes options…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les ping avec le parefeu Packet-Filter (PF)]]></summary>
        <published>2019-10-31T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e4958059-6a84-eb04-9f14-553eae51fd40</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vm-debian-10-buster/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [OpenBSD :: Virtualisation] Debian Buster (10.x)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Buster" scheme="http://doc.huc.fr.eu.org/fr/tags/buster/" />
        <category term="vmd" scheme="http://doc.huc.fr.eu.org/fr/tags/vmd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La virtualisation de machine virtuelle sous OpenBSD est officiellement
disponible nativement dans le système de base depuis OpenBSD 5.9.</p>
<ul>
<li>Version : <strong>native</strong></li>
<li>OS : OpenBSD <strong>6.5</strong>, <strong>6.6</strong></li>
</ul>
<h2 id="pré-requis">Pré-requis</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Ce tutoriel ne documente pas dans les moindres détails
les phases d&rsquo;installation, voire de configuration.</p>
<p>Il est <strong>VRAIMENT</strong> nécessaire de faire preuve de réflexion, discernement
et d&rsquo;avoir un minimum de compétences, pour comprendre les liens entre les
différentes briques !</p>
<p>Merci de votre compréhension…</p>
</div>

<p>Il est nécessaire que votre machine sur laquelle vous souhaitez virtualiser
ait un CPU compatible avec les fonctions adéquates. Pour le vérifier, tapez
dans votre terminal/console la commande suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>:$ dmesg | egrep <span style="color:#48b685">&#39;(VMX/EPT|SVM/RVI)&#39;</span>
</span></span></code></pre></div><p>La réponse du système doit être :</p>
<p>⇒ pour CPU Intel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT
</span></span></code></pre></div><p>⇒ pour CPU Amd :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: SVM/RVI
</span></span></code></pre></div><p>Si aucune ligne n&rsquo;apparaît, aucune virtualisation ne sera possible. Par
acquis de conscience, vérifiez votre BIOS|UEFI que celle-ci ne soit pas
désactivée.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>De même, en rapport avec les failles CPU relatives à Meltdown, Spectre,
certains CPU Intel sont patchés pour remédier à <a href="https://www.intel.fr/content/www/fr/fr/architecture-and-technology/l1tf.html" rel="external">L1TF</a>.
Sous OpenBSD, ces CPU reçoivent un correctif approprié. Malheureusement,
cela impacte la virtualisation et rend celle-ci impossible.
Vous pouvez vous retrouver dans la situation où vous auriez un CPU
compatible, mais dans les faits, la virtualisation ne pourrait être
pleinement fonctionnelle.</p>
<p><em>Préférez AMD, en attendant ARM…</em></p>
</div>

<hr>
<p>Il est nécessaire d&rsquo;installer le firmware <code>vmm</code> pour que le kernel gère.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# fw_update vmm
</span></span></code></pre></div><hr>
<p>Par convention, créons un répertoire &lsquo;&lsquo;vm&rsquo;&rsquo; dans notre répertoire personnel,
et nous travaillerons à partir de celui-ci :  <br>
<code>:$ mkdir vm &amp;&amp; cd vm</code></p>
<h3 id="précisions-réseaux">Précisions réseaux</h3>
<ul>
<li>
<p>L&rsquo;interface <code>vether0</code> de l&rsquo;hôte aura pour adresse IPv4 : <code>192.168.0.1</code>,
cette adresse IP sera l&rsquo;adresse de la passerelle pour l&rsquo;interface réseau de
la VM.</p>
</li>
<li>
<p>L&rsquo;interface <code>enp0s3</code> de la VM Debian aura pour adresse IPv4 : <code>192.168.0.2</code></p>
</li>
<li>
<p>Dans les deux cas, le masque de réseau est de 24 bits.</p>
</li>
<li>
<p>Le serveur DNS renseigné dans le fichier <code>/etc/resolv.conf</code> de la VM de
Debian est, par convention <code>1.1.1.1</code>. C&rsquo;est celui de Cloudfare.  <br>
Mais il peut être très bien tout autre, pourvu qu&rsquo;il soit respectueux
de la confidentialité… tel que ceux de Quad9, par exemple !</p>
</li>
<li>
<p>Ce même serveur DNS peut être renseigné dans la règle PF de redirection
de flux DNS vers la VM.</p>
</li>
</ul>
<h2 id="création-de-limage-qcow2">Création de l&rsquo;image qcow2</h2>
<p>Dans les deux cas présentés, nous commencerons par créer la VM, très simplement
avec l&rsquo;outil natif à OpenBSD, nommé <code>vmctl</code> :</p>
<ul>
<li>OpenBSD ≤ 6.5 : <code>:$ vmctl create ~/vm/buster.qcow2 -s 10G</code></li>
<li>OpenBSD ≥ 6.6 : <code>:$ vmctl create -s 10G ~/vm/buster.qcow2</code></li>
</ul>
<h2 id="téléchargement-de-liso-debian">Téléchargement de l&rsquo;iso Debian</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>ATTENTION, vérifiez à l&rsquo;URL suivante le nom de l&rsquo;image iso de debian : <br>
<a href="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/" rel="external">https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/</a></p>
<p>Et, modifiez en conséquence le code ci-dessous !</p>
</div>

<p>Téléchargeons l&rsquo;iso Debian :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ ftp https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/<span style="color:#5bc4bf">{</span>debian-10.1.0-amd64-netinst.iso,SHA512SUMS<span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>Trying 2001:6b0:19::173...
</span></span><span style="display:flex;"><span>Trying 2001:6b0:19::165...
</span></span><span style="display:flex;"><span>Trying 194.71.11.165...
</span></span><span style="display:flex;"><span>Requesting https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.1.0-amd64-netinst.iso
</span></span><span style="display:flex;"><span>Redirected to https://gemmei.ftp.acc.umu.se/debian-cd/current/amd64/iso-cd/debian-10.1.0-amd64-netinst.iso
</span></span><span style="display:flex;"><span>Trying 2001:6b0:19::137...
</span></span><span style="display:flex;"><span>Trying 194.71.11.137...
</span></span><span style="display:flex;"><span>Requesting https://gemmei.ftp.acc.umu.se/debian-cd/current/amd64/iso-cd/debian-10.1.0-amd64-netinst.iso
</span></span><span style="display:flex;"><span>100% |*************************************************************************************************************************************************************|   <span style="color:#f99b15">335</span> MB    00:54
</span></span><span style="display:flex;"><span><span style="color:#f99b15">351272960</span> bytes received in 54.52 seconds <span style="color:#5bc4bf">(</span>6.14 MB/s<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Trying 2001:6b0:19::165...
</span></span><span style="display:flex;"><span>Trying 2001:6b0:19::173...
</span></span><span style="display:flex;"><span>Trying 194.71.11.173...
</span></span><span style="display:flex;"><span>Requesting https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS
</span></span><span style="display:flex;"><span>100% |*************************************************************************************************************************************************************|   <span style="color:#f99b15">658</span>       00:00
</span></span><span style="display:flex;"><span><span style="color:#f99b15">658</span> bytes received in 0.00 seconds <span style="color:#5bc4bf">(</span>639.20 KB/s<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Une fois téléchargée, vérifions sa somme de contrôle :</p>
<pre tabindex="0"><code>:$ sha512 -C SHA512SUMS debian-10.1.0-amd64-netinst.iso
(SHA512) debian-10.1.0-amd64-netinst.iso: OK
</code></pre><p>Si <strong>OK</strong>, alors c&rsquo;est bon… <span class="red">sinon, re-téléchargez</span>
 !</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration se trouve être <code>/etc/vm.conf</code>. Il faut écrire
votre compte identifiant dans la variable <code>USER</code>, cela permettra à votre
utilisateur d&rsquo;utiliser l&rsquo;outil <code>vmctl</code>…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#ef6155">USER</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">VM</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/home/</span><span style="color:#ef6155">$USER</span><span style="color:#48b685">/vm&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>switch <span style="color:#48b685">&#34;sw&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    interface bridge0
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>vm <span style="color:#48b685">&#34;buster&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    disable
</span></span><span style="display:flex;"><span>    memory 1G
</span></span><span style="display:flex;"><span>    cdrom <span style="color:#ef6155">$VM</span>/debian-10.1.0-amd64-netinst.iso
</span></span><span style="display:flex;"><span>    disk <span style="color:#ef6155">$VM</span>/debian.qcow2
</span></span><span style="display:flex;"><span>    interface <span style="color:#5bc4bf">{</span> switch <span style="color:#48b685">&#34;sw&#34;</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>    owner <span style="color:#ef6155">$USER</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><hr>
<p>Vérifiez la configuration à l&rsquo;aide de l&rsquo;option <code>-n</code> de vmd :</p>
<p><code>:$ vmd -n</code></p>
<hr>
<p>Après avoir configuré les <a href="/fr/sys/openbsd/vm-debian-10-buster/#interfaces-réseaux">interfaces réseaux</a>,
il faut maintenant démarrer le service de gestion des VMs :</p>
<pre tabindex="0"><code>:# rcctl enable vmd
:# rcctl start vmd
</code></pre><p>Il est assurément utile de s&rsquo;occuper de la <a href="/fr/sys/openbsd/vm-debian-10-buster/#nat">traduction d&rsquo;adresses réseaux</a>,
et aussi des <a href="/fr/sys/openbsd/vm-debian-10-buster/#pf">règles du parefeu</a>…</p>
<h3 id="interfaces-réseaux">Interfaces réseaux</h3>
<p>Créons les interfaces réseaux nécessaires que sont <code>vether0</code> et <code>bridge0</code>
qui permettront un contrôle fin de l&rsquo;adressage IP et des règles PF.</p>
<p>Pour l&rsquo;interface <code>vether0</code>, il est possible d&rsquo;utiliser n&rsquo;importe quelle
classe privée IPv4 <em>(A: 10.0/8 ; B: 172.0.0/16 ; C: 192.168.0.0/24)</em> -
nous utiliserons un type de classe C privée, telle que <code>192.168.0.x</code>.
<em>Après tout, nous n&rsquo;avons pas plus de 256 VM à administrer</em>… ;)</p>
<h4 id="bridge0">bridge0</h4>
<p>Le fichier relatif est <code>/etc/hostname.bridge0</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>add vether0
</span></span></code></pre></div><h4 id="vether0">vether0</h4>
<p>Le fichier relatif est <code>/etc/hostname.vether0</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>inet 192.168.0.1 255.255.255.0
</span></span></code></pre></div><hr>
<p>Une fois les fichiers d&rsquo;interfaces créés, donnez des droits 0600 dessus,
puis démarrez les deux interfaces :</p>
<pre tabindex="0"><code>:# chmod 0600 /etc/hostname.{bridge,vether}0
:# sh /etc/netstart {bridge,vether}0
</code></pre><h3 id="nat">NAT</h3>
<p>Pour nous faciliter la vie avec notre futur VM, nous allons autoriser la
redirection des paquets IP, pour qu&rsquo;elle puisse communiquer sur Internet -
<em>ne serait-ce que pour faire les mises à jour</em>…</p>
<p>Dans un terminal/console, écrivez :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# sysctl net.inet.ip.forwarding<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>:# sysctl net.inet6.ip6.forwarding<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span></code></pre></div><p>La première ligne est pour IPv4, la seconde pour IPv6.</p>
<p>Puis, pour garder les paramètres au redémarrage, modifiez le fichier
<code>/etc/sysctl.conf</code> pour ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">net.inet.ip.forwarding</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">net.inet6.ip6.forwarding</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si vous ne voulez pas que votre VM soit &ldquo;visible&rdquo; sur le réseau,
n&rsquo;activez pas la traduction d&rsquo;adresses réseaux !</div>

<h3 id="pf">PF</h3>
<p>Il sera ensuite nécessaire de modifier le fichier <code>/etc/pf.conf</code> ajouter
au moins les règles suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">domain</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;1.1.1.1&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>match out on egress from <span style="color:#5bc4bf">(</span>vether0:network<span style="color:#5bc4bf">)</span> to any nat-to <span style="color:#5bc4bf">(</span>egress<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pass in quick proto <span style="color:#5bc4bf">{</span> udp tcp <span style="color:#5bc4bf">}</span> from <span style="color:#5bc4bf">(</span>vether0:network<span style="color:#5bc4bf">)</span> to any port domain rdr-to <span style="color:#ef6155">$domain</span> port domain
</span></span><span style="display:flex;"><span>pass on vether0 from 127.0.0.1 to any
</span></span><span style="display:flex;"><span>pass on vether0 from <span style="color:#5bc4bf">(</span>vether0:network<span style="color:#5bc4bf">)</span> to any
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><ul>
<li>
<p>La première règle indique que tout ce qui vient du réseau lié à l&rsquo;interface
<code>vether0</code> doit être traduit (NATé) vers les adresses IP faisant partie
du groupe <code>egress</code>.</p>
</li>
<li>
<p>La deuxième règle demande à ce que tout flux entrant qui vient du service
<code>domain</code> (port <code>53</code>) sur les protocoles <code>udp</code> et <code>tcp</code> depuis
le réseau lié à l&rsquo;interface <code>vether0</code> soit redirigée vers le service
en question. <br>
L&rsquo;adresse IPv4 <code>1.1.1.1</code> est celle du serveur DNS de Cloudflare ;
elle peut être très bien celle de tout autre serveur DNS.</p>
</li>
<li>
<p>La troisième règle autorise tout ce qui passe en entrée et en sortie
sur l&rsquo;interface <code>vether0</code> depuis l&rsquo;interface <code>locale</code>  vers ailleurs…</p>
</li>
<li>
<p>Quant à la quatrième, elle autorise tout du réseau, en entrée et en sortie,
lié à l&rsquo;interface <code>vether0</code> vers partout !</p>
</li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<ul>
<li>
<p>Démarrer la VM pour l&rsquo;installation :</p>
<ul>
<li>Pour OpenBSD ≤ 6.5 : <code>:$ vmctl start buster -c</code></li>
<li>Pour OpenBSD ≥ 6.6 : <code>:$ vmctl start -c buster</code></li>
</ul>
</li>
<li>
<p>Choisir le menu &ldquo;Install&rdquo; - <strong>NE PAS APPUYEZ sur la touche <kbd>ENTRÉE</kbd></strong> ;
appuyez sur la touche <kbd>TAB</kbd> pour éditer le menu. Il va falloir
corriger la ligne :</p>
</li>
</ul>
<pre tabindex="0"><code>&gt; /install.amd/vmlinuz vga=788 initrd=/install.amd/initrd.gz --- quiet` en
&gt; /install.amd/vmlinuz vga=off initrd=/install.amd/initrd.gz --- quiet console=ttyS0,115200n8` ;
</code></pre><pre><code>une fois, transformée, appuyez sur la touche &lt;kbd&gt;ENTRÉE&lt;/kbd&gt; !
</code></pre>
<p>Le reste de l&rsquo;installation de Debian se fait comme tout autre installation…
à vous de paramétrer selon vos besoins.</p>
<p>Une fois l&rsquo;installation terminée, ne redémarrez pas par le biais de l&rsquo;installateur,
choisissez d&rsquo;exécuter le shell, puis écrivez la commande : <br>
<code>:# halt</code> afin d&rsquo;arrêter la VM proprement !</p>
<h3 id="pour-finir">Pour finir</h3>
<p>Une fois que vous avez fini l&rsquo;installation de Debian dans votre VM, que
vous avez fait les derniers réglages nécessaires pour son bon fonctionnement,
pensez à éditer à nouveau le fichier <code>/etc/vm.conf</code> :</p>
<ul>
<li>
<p>Supprimer/commenter toute écriture relative à la déclaration <code>cdrom</code>…</p>
</li>
<li>
<p>Remplacer le mot clé <code>disable</code> par <code>enable</code> pour la VM <code>debian</code> - <br>
si vous désirez que la VM correspondante démarre, soit lors du démarrage
de votre machine, si et seulement si le service <code>vmd</code> est bien actif
et démarré lors du processus de démarrage machine, soit lorsque vous
redémarrez le service <code>vmd</code> lui-même par vos soins.</p>
</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="vmctl-vmm-bios-firmware-not-found">vmctl vmm bios firmware not found</h3>
<p>Vous n&rsquo;avez tout simplement pas installé le firmware <strong>vmm</strong> !</p>
<h2 id="documentations">Documentations</h2>
<p>Un tout petit laïus sur la commande <code>vmctl</code> : <br>
<code>:$ man vmctl</code> pour découvrir les différentes options bien utiles,
dont <code>show</code>, <code>status</code>, <code>start</code>, et <code>stop</code> qu&rsquo;il semble nécessaire de maîtriser !</p>
<ul>
<li>
<p>Merci de lire la documentation officielle <em><em>FAQ Virtualisation</em>-</em> <a href="https://www.openbsd.org/faq/faq16.html" rel="external">EN</a>
afin de bien comprendre le sujet, les différentes informations nécessaires
à une meilleure préhension de celui-ci.</p>
</li>
<li>
<p>Il est fortement intéressant de lire les pages de manuels, en anglais, relative
à :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/vmctl.8" title="Page du Manuel OpenBSD pour : vmctl">vmctl(8)</a>
,</li>
<li>
<a class="man" href="https://man.openbsd.org/vmd.8" title="Page du Manuel OpenBSD pour : vmd">vmd(8)</a>
,</li>
<li>
<a class="man" href="https://man.openbsd.org/vm.conf.5" title="Page du Manuel OpenBSD pour : vm.conf">vm.conf(5)</a>
,</li>
<li>
<a class="man" href="https://man.openbsd.org/vmm.4" title="Page du Manuel OpenBSD pour : vmm">vmm(4)</a>
</li>
<li>sans oublier 
<a class="man" href="https://man.openbsd.org/doas.1" title="Page du Manuel OpenBSD pour : doas">doas(1)</a>
, au besoin…</li>
</ul>
</li>
</ul>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Virtualiser Debian Buster (10.x) sous OpenBSD grâce à vmd]]></summary>
        <published>2019-10-15T22:00:34+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:90fdf212-3d3a-ed2e-4f5b-d9c333c33a04</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/python/env-python-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Python : environnement virtuel sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <category term="Environnement" scheme="http://doc.huc.fr.eu.org/fr/tags/environnement/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<ul>
<li>OS : OpenBSD 6.x</li>
</ul>
<p>Depuis OpenBSD 6.0, l&rsquo;option de montage <code>wxallowed</code> est configuré par
défaut sur <code>/usr/local</code>. Pour ceux qui ne le savent pas, c&rsquo;est une protection
système. Si la partition a cette option, les logiciels sont autorisés à
fonctionner depuis cette partition, sinon ils ne pourront fonctionner et
émettront un message de violation <code>W^X</code>, tel que :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:$ dmesg | grep wxallowed
/home/hs/.local/share/virtualenvs/mybeautifullproject-q1koN8ay/bin/python3(26392): W^X binary outside wxallowed mountpoint`
</code></pre><p>De fait, puisque seul <code>/usr/local</code> a cette option activée, si vous tentez
d&rsquo;exécuter un programme depuis, par exemple, votre <code>$HOME</code>, cela ne fonctionnera
pas. Et, c&rsquo;est tout le problème avec les environnements Python qui doivent
fonctionner dans votre répertoire personnel.</p>
<p>Dans les faits, voici ce qui se passe pour <code>virtualenv</code> :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:$ virtualenv mybeautifullproject
Using base prefix &#39;/usr/local&#39;
New python executable in $HOME/python/mybeautifullproject.py/mybeautifullproject/bin/python3
Also creating executable in $HOME/python/mybeautifullproject.py/mybeautifullproject/bin/python
ERROR: The executable $HOME/python/mybeautifullproject.py/mybeautifullproject/bin/python3 could not be run: [Errno 13] Permission denied: &#39;$HOME/python/mybeautifullproject.py/mybeautifullproject/bin/python
</code></pre><p>C&rsquo;est pareil pour <code>pipenv</code> :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:$ pipenv install requests
Warning: the environment variable LANG is not set!
We recommend setting this in ~/.profile (or equivalent) for proper expected behavior.
Creating a virtualenv for this project…
Pipfile: $HOME/python/mybeautifullproject.py/Pipfile
Using /usr/local/bin/python3 (3.6.8) to create virtualenv…
⠇ Creating virtual environment...Already using interpreter /usr/local/bin/python3
Using base prefix &#39;/usr/local&#39;
New python executable in $HOME/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3
Also creating executable in $HOME/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python
ERROR: The executable $HOME/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3 could not be run: [Errno 13] Permission denied: &#39;$HOME/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3&#39;

✘ Failed creating virtual environment
[pipenv.exceptions.VirtualenvCreationException]:   File &#34;$HOME/.local/lib/python3.6/site-packages/pipenv/cli/command.py&#34;, line 254, in install
[pipenv.exceptions.VirtualenvCreationException]:       editable_packages=state.installstate.editables,
[pipenv.exceptions.VirtualenvCreationException]:   File &#34;$HOME/.local/lib/python3.6/site-packages/pipenv/core.py&#34;, line 1741, in do_install
[pipenv.exceptions.VirtualenvCreationException]:       pypi_mirror=pypi_mirror,
[pipenv.exceptions.VirtualenvCreationException]:   File &#34;$HOME/.local/lib/python3.6/site-packages/pipenv/core.py&#34;, line 574, in ensure_project
[pipenv.exceptions.VirtualenvCreationException]:       pypi_mirror=pypi_mirror,
[pipenv.exceptions.VirtualenvCreationException]:   File &#34;$HOME/.local/lib/python3.6/site-packages/pipenv/core.py&#34;, line 506, in ensure_virtualenv
[pipenv.exceptions.VirtualenvCreationException]:       python=python, site_packages=site_packages, pypi_mirror=pypi_mirror
[pipenv.exceptions.VirtualenvCreationException]:   File &#34;$HOME/.local/lib/python3.6/site-packages/pipenv/core.py&#34;, line 935, in do_create_virtualenv
[pipenv.exceptions.VirtualenvCreationException]:       extra=[crayons.blue(&#34;{0}&#34;.format(c.err)),]
[pipenv.exceptions.VirtualenvCreationException]:
Failed to create virtual environment.
</code></pre><p>D&rsquo;autant que ce n&rsquo;est vraiment pas un problème de droits utilisateurs :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:$ ls -al mybeautifullproject/
total 40
drwxr-xr-x  5 hs  hs  512 Jun  3 01:43 ./
drwxr-xr-x  3 hs  hs  512 Jun  3 01:44 ../
drwxr-xr-x  2 hs  hs  512 Jun  3 01:43 bin/
drwxr-xr-x  2 hs  hs  512 Jun  3 01:43 include/
drwxr-xr-x  3 hs  hs  512 Jun  3 01:43 lib/

:$ ls -al mybeautifullproject/bin/
total 40
drwxr-xr-x  2 hs  hs    512 Jun  3 01:43 ./
drwxr-xr-x  5 hs  hs    512 Jun  3 01:43 ../
lrwxr-xr-x  1 hs  hs      7 Jun  3 01:43 python@ -&gt; python3
-rwxr-xr-x  1 hs  hs  10680 Jun  3 01:43 python3*
lrwxr-xr-x  1 hs  hs      7 Jun  3 01:43 python3.6@ -&gt; python3
</code></pre><h2 id="configuration">Configuration</h2>
<p>Une petite modification système va faciliter notre vie - puisque <code>/usr/local</code>
est la seule partition autorisée à l&rsquo;exécution des programmes qui nécessitent
la violation <code>W^X</code> :</p>
<ul>
<li>Création d&rsquo;un répertoire utilisateur dedans : <br>
<code>:# mkdir -p /usr/local/${my_user}/python</code></li>
<li>Attribution des droits utilisateur et groupe correcte : <br>
<code>:# chown -R ${my_user}:wheel /usr/local/${my_user}</code></li>
<li>Création d&rsquo;un lien symbolique : <br>
<code>:# ln -s /usr/local/${my_user}/python $home/python</code></li>
</ul>
<p>Remplacez <code>${my_user}</code> par votre identifiant de session ;)</p>
<p>Si vous avez la bonne idée d&rsquo;utiliser l&rsquo;outil <code>pipenv</code>, il faudra créer
un nouveau répertoire et le lier symboliquement ; lisez la section
<a href="/fr/dev/python/env-python-openbsd/#tldr">TL;DR</a> ci-dessous…</p>
<h2 id="tldr">TL;DR</h2>
<p>Remplacez &lsquo;&rsquo;${my_user}&rsquo;&rsquo; par votre identifiant de session !</p>
<p>⇒ Pour <strong>virtualenv</strong> :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:# mkdir -p /usr/local/${my_user}/python
:# chown -R ${my_user}:wheel /usr/local/${my_user}
:# ln -s /usr/local/${my_user}/python $home/python`
</code></pre><p>⇒ Pour <strong>pipenv</strong>, il faut rajouter à ce qui suit au-dessus : \</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:$ mkdir /usr/local/$USER/python/virtualenvs
:$ ln -s /usr/local/$USER/python/virtualenvs $HOME/.local/share/virtualenvs`
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li>La documentation de <strong>pipenv</strong> - <em>en anglais</em> : <a href="https://pipenv.readthedocs.io/en/latest/" rel="external">https://pipenv.readthedocs.io/en/latest/</a></li>
<li>À-propos de l&rsquo;option de montage <strong>wxallowed</strong> : le Guide de Migration OpenBSD 5.9 vers 6.0 - <a href="https://www.openbsd.org/faq/upgrade60.html" rel="external">EN</a> / <a href="https://wiki.openbsd.fr.eu.org/doku.php/openbsd.org/faq/upgrade60#changement-de-configuration-et-de-syntaxe" rel="external">FR</a></li>
<li>La <a href="https://forum.openbsd.fr.eu.org/showthread.php?tid=2352&amp;pid=18773#pid18773" rel="external">réponse</a> expliquée sur le forum &ldquo;obsd4*&rdquo;</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>Ce tutoriel n&rsquo;existerait pas sans <a href="https://ybad.name/sdj.html" rel="external">Xavier</a>…</li>
<li>et, sans cet <a href="https://deftly.net/posts/2017-10-12-using-cabal-on-openbsd.html" rel="external">article</a> anglais, nommé &ldquo;<em><strong>Using cabal on OpenBSD</strong></em>&rdquo;</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser les environnements Python virtuels sous OpenBSD (W^X)]]></summary>
        <published>2019-06-19T12:03:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0bd7583d-e117-7f0a-e973-3bbd3253a50b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/env-python-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Python : environnement virtuel sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<ul>
<li>OS : OpenBSD 6.x</li>
</ul>
<p>Depuis OpenBSD 6.0, l&rsquo;option de montage <code>wxallowed</code> est configuré par
défaut sur <code>/usr/local</code>. Pour ceux qui ne le savent pas, c&rsquo;est une protection
système. Si la partition a cette option, les logiciels sont autorisés à
fonctionner depuis cette partition, sinon ils ne pourront fonctionner et
émettront un message de violation <code>W^X</code>, tel que :</p>
<pre tabindex="0"><code>:$ dmesg | grep wxallowed
/home/hs/.local/share/virtualenvs/mybeautifullproject-q1koN8ay/bin/python3(26392): W^X binary outside wxallowed mountpoint
</code></pre><p>De fait, puisque seul <code>/usr/local</code> a cette option activée, si vous tentez
d&rsquo;exécuter un programme depuis, par exemple, votre <code>$HOME</code>, cela ne fonctionnera
pas. Et, c&rsquo;est tout le problème avec les environnements Python qui doivent
fonctionner dans votre répertoire personnel.</p>
<p>Dans les faits, voici ce qui se passe pour <code>virtualenv</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ virtualenv mybeautifullproject
</span></span><span style="display:flex;"><span>Using base prefix <span style="color:#48b685">&#39;/usr/local&#39;</span>
</span></span><span style="display:flex;"><span>New python executable in <span style="color:#ef6155">$HOME</span>/python/mybeautifullproject.py/mybeautifullproject/bin/python3
</span></span><span style="display:flex;"><span>Also creating executable in <span style="color:#ef6155">$HOME</span>/python/mybeautifullproject.py/mybeautifullproject/bin/python
</span></span><span style="display:flex;"><span>ERROR: The executable <span style="color:#ef6155">$HOME</span>/python/mybeautifullproject.py/mybeautifullproject/bin/python3 could not be run: <span style="color:#5bc4bf">[</span>Errno 13<span style="color:#5bc4bf">]</span> Permission denied: <span style="color:#ef6155">&#39;</span><span style="color:#ef6155">$HOME</span>/python/mybeautifullproject.py/mybeautifullproject/bin/python
</span></span></code></pre></div><p>C&rsquo;est pareil pour <code>pipenv</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ pipenv install requests
</span></span><span style="display:flex;"><span>Warning: the environment variable LANG is not set!
</span></span><span style="display:flex;"><span>We recommend setting this in ~/.profile <span style="color:#5bc4bf">(</span>or equivalent<span style="color:#5bc4bf">)</span> <span style="color:#815ba4">for</span> proper expected behavior.
</span></span><span style="display:flex;"><span>Creating a virtualenv <span style="color:#815ba4">for</span> this project…
</span></span><span style="display:flex;"><span>Pipfile: <span style="color:#ef6155">$HOME</span>/python/mybeautifullproject.py/Pipfile
</span></span><span style="display:flex;"><span>Using /usr/local/bin/python3 <span style="color:#5bc4bf">(</span>3.6.8<span style="color:#5bc4bf">)</span> to create virtualenv…
</span></span><span style="display:flex;"><span>⠇ Creating virtual environment...Already using interpreter /usr/local/bin/python3
</span></span><span style="display:flex;"><span>Using base prefix <span style="color:#48b685">&#39;/usr/local&#39;</span>
</span></span><span style="display:flex;"><span>New python executable in <span style="color:#ef6155">$HOME</span>/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3
</span></span><span style="display:flex;"><span>Also creating executable in <span style="color:#ef6155">$HOME</span>/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python
</span></span><span style="display:flex;"><span>ERROR: The executable <span style="color:#ef6155">$HOME</span>/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3 could not be run: <span style="color:#5bc4bf">[</span>Errno 13<span style="color:#5bc4bf">]</span> Permission denied: <span style="color:#48b685">&#39;$HOME/.local/share/virtualenvs/mybeautifullproject.py-oFlnu9vD/bin/python3&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>✘ Failed creating virtual environment
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:   File <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.local/lib/python3.6/site-packages/pipenv/cli/command.py&#34;</span>, line 254, in install
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:       <span style="color:#ef6155">editable_packages</span><span style="color:#5bc4bf">=</span>state.installstate.editables,
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:   File <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.local/lib/python3.6/site-packages/pipenv/core.py&#34;</span>, line 1741, in do_install
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:       <span style="color:#ef6155">pypi_mirror</span><span style="color:#5bc4bf">=</span>pypi_mirror,
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:   File <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.local/lib/python3.6/site-packages/pipenv/core.py&#34;</span>, line 574, in ensure_project
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:       <span style="color:#ef6155">pypi_mirror</span><span style="color:#5bc4bf">=</span>pypi_mirror,
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:   File <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.local/lib/python3.6/site-packages/pipenv/core.py&#34;</span>, line 506, in ensure_virtualenv
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:       <span style="color:#ef6155">python</span><span style="color:#5bc4bf">=</span>python, <span style="color:#ef6155">site_packages</span><span style="color:#5bc4bf">=</span>site_packages, <span style="color:#ef6155">pypi_mirror</span><span style="color:#5bc4bf">=</span>pypi_mirror
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:   File <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$HOME</span><span style="color:#48b685">/.local/lib/python3.6/site-packages/pipenv/core.py&#34;</span>, line 935, in do_create_virtualenv
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:       <span style="color:#ef6155">extra</span><span style="color:#5bc4bf">=[</span>crayons.blue<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#34;{0}&#34;</span>.format<span style="color:#5bc4bf">(</span>c.err<span style="color:#5bc4bf">))</span>,<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>pipenv.exceptions.VirtualenvCreationException<span style="color:#5bc4bf">]</span>:
</span></span><span style="display:flex;"><span>Failed to create virtual environment.
</span></span></code></pre></div><p>D&rsquo;autant que ce n&rsquo;est vraiment pas un problème de droits utilisateurs :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ls -al mybeautifullproject/
</span></span><span style="display:flex;"><span>total <span style="color:#f99b15">40</span>
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">5</span> hs  hs  <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 ./
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">3</span> hs  hs  <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:44 ../
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">2</span> hs  hs  <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 bin/
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">2</span> hs  hs  <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 include/
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">3</span> hs  hs  <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 lib/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ ls -al mybeautifullproject/bin/
</span></span><span style="display:flex;"><span>total <span style="color:#f99b15">40</span>
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">2</span> hs  hs    <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 ./
</span></span><span style="display:flex;"><span>drwxr-xr-x  <span style="color:#f99b15">5</span> hs  hs    <span style="color:#f99b15">512</span> Jun  <span style="color:#f99b15">3</span> 01:43 ../
</span></span><span style="display:flex;"><span>lrwxr-xr-x  <span style="color:#f99b15">1</span> hs  hs      <span style="color:#f99b15">7</span> Jun  <span style="color:#f99b15">3</span> 01:43 python@ -&gt; python3
</span></span><span style="display:flex;"><span>-rwxr-xr-x  <span style="color:#f99b15">1</span> hs  hs  <span style="color:#f99b15">10680</span> Jun  <span style="color:#f99b15">3</span> 01:43 python3*
</span></span><span style="display:flex;"><span>lrwxr-xr-x  <span style="color:#f99b15">1</span> hs  hs      <span style="color:#f99b15">7</span> Jun  <span style="color:#f99b15">3</span> 01:43 python3.6@ -&gt; python3
</span></span></code></pre></div><h2 id="configuration">Configuration</h2>
<p>Une petite modification système va faciliter notre vie - puisque <code>/usr/local</code>
est la seule partition autorisée à l&rsquo;exécution des programmes qui nécessitent
la violation <code>W^X</code> :</p>
<ul>
<li>
<p>Création d&rsquo;un répertoire utilisateur dedans : <br>
<code>:# mkdir -p /usr/local/${my_user}/python</code></p>
</li>
<li>
<p>Attribution des droits utilisateur et groupe correcte : <br>
<code>:# chown -R ${my_user}:wheel /usr/local/${my_user}</code></p>
</li>
<li>
<p>Création d&rsquo;un lien symbolique : <br>
<code>:# ln -s /usr/local/${my_user}/python $home/python</code></p>
</li>
</ul>
<p>Remplacez <code>${my_user}</code> par votre identifiant de session ;)</p>
<p>Si vous avez la bonne idée d&rsquo;utiliser l&rsquo;outil <code>pipenv</code>, il faudra créer
un nouveau répertoire et le lier symboliquement ; lisez la section <a href="/fr/sys/openbsd/env-python-openbsd/#tldr">TL;DR</a>
ci-dessous…</p>
<h2 id="tldr">TL;DR</h2>
<p>Remplacez &lsquo;&rsquo;${my_user}&rsquo;&rsquo; par votre identifiant de session !</p>
<p>⇒ Pour <strong>virtualenv</strong> :</p>
<pre tabindex="0"><code>:# mkdir -p /usr/local/${my_user}/python
:# chown -R ${my_user}:wheel /usr/local/${my_user}
:# ln -s /usr/local/${my_user}/python $home/python
</code></pre><p>⇒ Pour <strong>pipenv</strong>, il faut rajouter à ce qui suit au-dessus :</p>
<pre tabindex="0"><code>:$ mkdir /usr/local/$USER/python/virtualenvs
:$ ln -s /usr/local/$USER/python/virtualenvs $HOME/.local/share/virtualenvs
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li>La documentation de <strong>pipenv</strong> - <em>en anglais</em> :
<a href="https://pipenv.readthedocs.io/en/latest/" rel="external">https://pipenv.readthedocs.io/en/latest/</a></li>
<li>À-propos de l&rsquo;option de montage <strong>wxallowed</strong> : le Guide de Migration OpenBSD
5.9 vers 6.0 - <a href="https://www.openbsd.org/faq/upgrade60.html" rel="external">EN</a></li>
<li>La <a href="https://forum.openbsd.fr.eu.org/showthread.php?tid=2352&amp;pid=18773#pid18773" rel="external">réponse</a> expliquée sur le forum &ldquo;obsd4*&rdquo;</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>Ce tutoriel n&rsquo;existerait pas sans <a href="https://ybad.name/sdj.html" rel="external">Xavier</a>…</li>
<li>et, sans cet <a href="https://deftly.net/posts/2017-10-12-using-cabal-on-openbsd.html" rel="external">article</a> anglais, nommé &ldquo;<em><strong>Using cabal on OpenBSD</strong></em>&rdquo;</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser les environnements Python virtuels sous OpenBSD (W^X)]]></summary>
        <published>2019-06-19T12:03:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4bccc25a-ea7d-1881-03ca-8366786305f8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/android/synchronisation-xiaomi-nextcloud/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Xiaomi : Synchronisation avec Nextcloud et OpenSync (MIUI)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Xiaomi" scheme="http://doc.huc.fr.eu.org/fr/tags/xiaomi/" />
        <category term="Android" scheme="http://doc.huc.fr.eu.org/fr/tags/android/" />
        <category term="MIUI" scheme="http://doc.huc.fr.eu.org/fr/tags/miui/" />
        <category term="nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Le choix de l&rsquo;outil de synchronisation des données calendriers et de contacts
est délicat. Oubliez DavDroid/Davx5, la solution qui fonctionne est l&rsquo;usage
de l&rsquo;app &ldquo;<strong><a href="https://deependhulla.com/android-apps/opensync-app" rel="external">OpenSync</a></strong>&rdquo; — qui est un &ldquo;fork&rdquo; de la précédente application,
disponible sur n&rsquo;importe quel store -</p>
<p>Celle-ci demande l&rsquo;installation de l&rsquo;app &ldquo;Open Tasks&rdquo;, complémentaire pour
gérer les tâches.</p>
<p>Avant de chercher à paramétrer votre connexion vers votre nuage informatique,
tel Nextcloud, il faut configurer votre système MIUI.</p>
<ul>
<li>Testé sur interface :
<ul>
<li><a href="/fr/sys/android/synchronisation-xiaomi-nextcloud/#miui">MIUI</a> 8 (Android 6), 9 &amp; 10 (Android 7), 11 (Android 9)</li>
<li>puis <a href="/fr/sys/android/synchronisation-xiaomi-nextcloud/#android">Android</a> 9, 10 - <em>en effet, certains modèles
de smartphones Xiaomi n&rsquo;ont pas l&rsquo;interface MIUI installée</em></li>
</ul>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="android">Android</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ce qui suit concerne Android 9, 10 !</div>

<h4 id="android-paramètres">Android: Paramètres</h4>
<p>Le mode opératoire est le suivant :</p>
<p>Menu &ldquo;Paramètres&rdquo; &gt; &ldquo;Applis et notifications&rdquo; : recherchez &ldquo;OpenSync&rdquo;</p>
<hr>
<ul>
<li>
<p>Appuyez sur le choix &ldquo;Autorisations&rdquo; pour activer &ldquo;Agenda&rdquo;, &ldquo;Contacts&rdquo;
<sup><span class="orange">1</span>
</sup></p>
<ul>
<li>et appuyez sur &ldquo;Autorisations supplémentaires&rdquo; pour activer &ldquo;Tâches&rdquo;</li>
</ul>
</li>
<li>
<p>Ensuite, appuyez sur &ldquo;Options avancées&rdquo;<sup><span class="orange">2</span>
</sup>
qui laissera apparaître, entres autres, le choix &ldquo;Batterie&rdquo;. <br>
Appuyez dessus puis choisissez &ldquo;Optimisation de la batterie&rdquo;</p>
<ul>
<li>Là - <em>malheureusement, c&rsquo;est un peu mal conçu</em> - appuyez sur la liste &ldquo;Non optimisée&rdquo;
pour faire apparaître &ldquo;Toutes les applis&rdquo;, puis cherchez à nouveau &ldquo;OpenSync&rdquo;
pour sélectionner &ldquo;Ne pas optimiser&rdquo;, suivi de l&rsquo;appui sur le bouton OK.</li>
<li>Faites de même avec &ldquo;OpenTasks&rdquo;, puisque vous êtes dans la bonne rubrique ;)</li>
</ul>
</li>
</ul>
<p><sup><span class="orange">1</span>
</sup> <em>v10: il semble qu&rsquo;il faille
appuyer sur les noms &ldquo;Agenda&rdquo;, puis &ldquo;Contacts&rdquo; pour avoir accès au choix
d&rsquo;autoriser ou de refuser l&rsquo;autorisation</em></p>
<hr>
<p>Faites quasiment de même avec &ldquo;OpenTasks&rdquo; en validant les autorisations sur
&ldquo;Contacts&rdquo;, et en &ldquo;Autorisations supplémentaires&rdquo;, activez &ldquo;Tâches&rdquo;.</p>
<h4 id="android-avancées">Android: Avancées</h4>
<p>Pour finir, vérifiez dans les &ldquo;Options avancées&rdquo;<sup><span class="orange">2</span>
</sup>,
puis &ldquo;Batterie&rdquo; que &ldquo;Optimisation de la batterie&rdquo; soit bien positionnée sur
&ldquo;Non optimisée&rdquo; - <em>ce qui devrait être le cas, puisque paramétré précédemment ;
sinon, faites-le</em> !</p>
<p><sup><span class="orange">2</span>
</sup> <em>v10 : ce menu s&rsquo;appelle &ldquo;Préférences avancées&rdquo;</em></p>
<h3 id="miui">MIUI</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ce qui suit concerne MIUI 8, 9, 10, 11 !</div>

<h4 id="miui-paramètres">MIUI: Paramètres</h4>
<p>Menu &ldquo;Paramètres&rdquo; &gt; &ldquo;applications installées&rdquo;<sup><span class="orange">3</span>
</sup>,
cherchez &ldquo;OpenSync&rdquo; et appuyez sur le nom de l&rsquo;application.</p>
<p><sup><span class="orange">3</span>
</sup> <em>v11 : ce menu s&rsquo;appelle tout simplement &ldquo;Applis&rdquo;</em></p>
<hr>
<ul>
<li>
<p>Activez le &ldquo;Démarrage automatique&rdquo;</p>
</li>
<li>
<p>Appuyez sur &ldquo;Autorisations de l&rsquo;application&rdquo;, puis activez &ldquo;Agenda&rdquo;, &ldquo;Contacts&rdquo;</p>
<ul>
<li>et appuyez sur &ldquo;Autorisations supplémentaires&rdquo; pour activer &ldquo;Tâches&rdquo;</li>
</ul>
</li>
<li>
<p>Appuyez sur &ldquo;Autres autorisations&rdquo; pour au moins
&ldquo;Démarrer en arrière plan&rdquo; - <em>v11 : ce menu semble ne plus exister</em></p>
</li>
<li>
<p>Appuyez sur &ldquo;Économiseur de batterie&rdquo; pour choisir &ldquo;Pas de restriction&rdquo; -
si cette option n&rsquo;est pas choisie, au lieu de l&rsquo;option &ldquo;Économiseur de batterie (recommandée)&rdquo;,
OpenSync ne synchronisera pas correctement.</p>
</li>
</ul>
<hr>
<p>Toujours dans le menu &ldquo;Paramètres&rdquo;, à &ldquo;Autorisations&rdquo;, puis &ldquo;Gestion du démarrage automatique&rdquo;,
vérifiez que vous ayez bien &ldquo;OpenSync&rdquo; et &ldquo;OpenTasks&rdquo;, toutes les deux activées.</p>
<h4 id="miui-sécurité">MIUI: Sécurité</h4>
<p>Ensuite, dans l&rsquo;application &ldquo;Sécurité&rdquo; :</p>
<ul>
<li>tapez sur l&rsquo;icône &ldquo;Batterie&rdquo; puis</li>
<li>sélectionnez le choix &ldquo;Économiseur de batterie&rdquo;,</li>
<li>et vérifiez que les deux app &ldquo;OpenSync&rdquo; et &ldquo;OpenTasks&rdquo; aient bien leur
paramétrage d&rsquo;arrière plan sur &ldquo;Pas de restriction&rdquo;. <br>
Il suffit de cliquer sur l&rsquo;icône correspondante à l&rsquo;app, pour aboutir
sur le paramétrage en question.</li>
</ul>
<h3 id="opensync">OpenSync</h3>
<p>Maintenant, ouvrez l&rsquo;app &ldquo;OpenSync&rdquo;, et ajoutez votre paramétrage de connexion
vers votre serveur Nextcloud.</p>
<p>Puis redémarrez votre smartphone !</p>
<p>Ensuite, ouvrez à nouveau &ldquo;OpenSync&rdquo; et exécutez une synchronisation des
différentes données que vous avez paramétré.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://help.nextcloud.com/t/opensync-xiaomi-synchronization-issue/28108" rel="external">https://help.nextcloud.com/t/opensync-xiaomi-synchronization-issue/28108</a></li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment synchroniser les données d&#39;un smartphone de marque Xiaomi avec un nuage informatique, tel nextcloud]]></summary>
        <published>2019-06-18T15:28:31+02:00</published>
        <updated>2020-05-15T16:00:00+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d3b13644-c429-7a9a-3666-fbe6dfc1d550</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/php/php-composer-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP : Composer (sous OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP" scheme="http://doc.huc.fr.eu.org/fr/tags/php/" />
        <category term="Composer" scheme="http://doc.huc.fr.eu.org/fr/tags/composer/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Je ne présenterais ni <a href="https://php.net" rel="external">PHP</a>, ni
<a href="https://getcomposer.org" rel="external">composer</a>…</p>
<h2 id="installation">Installation</h2>
<p><code>pkg_add -v composer</code></p>
<p>Après l&rsquo;installation de <strong>Composer</strong>, faites une mise à jour de lui-même : <br>
<code>composer self-update</code></p>
<h2 id="configuration">Configuration</h2>
<p>De même, je ne détaillerais pas la configuration ni de PHP, ni de Composer,
d&rsquo;autant que par défaut pour ce dernier, il n&rsquo;y a rien à faire en soit -
<em>il est bien sûr possible de configurer certaines options…</em></p>
<h2 id="diagnostic">Diagnostic</h2>
<p>Pour finir, on exécute ensuite un petit diagnostic :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ composer diagnose
</span></span><span style="display:flex;"><span>Checking platform settings: OK
</span></span><span style="display:flex;"><span>Checking git settings: OK git version 2.46.1
</span></span><span style="display:flex;"><span>Checking http connectivity to packagist: OK
</span></span><span style="display:flex;"><span>Checking https connectivity to packagist: OK
</span></span><span style="display:flex;"><span>Checking github.com rate limit: OK
</span></span><span style="display:flex;"><span>Checking disk free space: OK
</span></span><span style="display:flex;"><span>Checking pubkeys:
</span></span><span style="display:flex;"><span>Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0  87719BA6 8F3BB723 4E5D42D0 84A14642
</span></span><span style="display:flex;"><span>Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B  0C708369 153E328C AD90147D AFE50952
</span></span><span style="display:flex;"><span>OK
</span></span><span style="display:flex;"><span>Checking Composer version: OK
</span></span><span style="display:flex;"><span>Checking Composer and its dependencies <span style="color:#815ba4">for</span> vulnerabilities: OK
</span></span><span style="display:flex;"><span>Composer version: 2.8.6
</span></span><span style="display:flex;"><span>PHP version: 8.2.28
</span></span><span style="display:flex;"><span>PHP binary path: /usr/local/bin/php-8.2
</span></span><span style="display:flex;"><span>OpenSSL version: LibreSSL 4.0.0
</span></span><span style="display:flex;"><span>curl version: 8.12.0 libz 1.3.1.1-motley ssl LibreSSL/4.0.0
</span></span><span style="display:flex;"><span>zip: extension present, unzip present, 7-Zip not available
</span></span></code></pre></div><p>Tous les voyants sont <strong>OK</strong>, Composer a la dernière version en cours,
et il s&rsquo;exécute bien avec la version de PHP désirée</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="php-7">PHP 7</h3>
<p>Pour information, par défaut, Composer est configuré pour être exécuté
avec php-7.0 sous la 6.4, et php-7.1 sous 6.5 - qu&rsquo;il installe en dépendances
<em>(avec femail*)</em></p>
<p>Le problème qui se pose est que si vous utilisez php-7.2, voire php-7.3,
Composer s&rsquo;exécutera avec l&rsquo;environnement PHP pour lequel il est paramétré par
défaut - <em>logique, vous me direz !</em></p>
<p>Alors, <strong>comment le contraindre ?</strong></p>
<p>Très facilement : <br>
<code># sed -i -e &quot;s/php-7.x/php-7.y/&quot; &quot;$(which composer)&quot;</code></p>
<p>où :</p>
<ul>
<li><code>7.x</code> est votre installation PHP par défaut,</li>
<li>et <code>7.y</code> la version de PHP que vous préférez utiliser, <em>telle que 7.2, par exemple…</em></li>
</ul>
<h3 id="error-do-not-run-composer-as-rootsuper-user">Error: Do not run Composer as root/super user</h3>
<p>Et, oui, il n&rsquo;est <span class="red">pas recommandé d'exécuter Composer avec des
droits d'administrateurs</span>
 - alors <strong>ne le faites pas</strong> !</p>
<p>Plus d&rsquo;informations, sur : <a href="https://getcomposer.org/root" rel="external">https://getcomposer.org/root</a></p>
<h3 id="error-missing-pubkey-for">Error: Missing pubkey for…</h3>
<p>Il est possible que lors du diagnostique, vous vous retrouvez avec ce
message d&rsquo;erreur sur fond rouge :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Checking pubkeys: FAIL
</span></span><span style="display:flex;"><span>Missing pubkey <span style="color:#815ba4">for</span> tags verification
</span></span><span style="display:flex;"><span>Missing pubkey <span style="color:#815ba4">for</span> dev verification
</span></span><span style="display:flex;"><span>Run composer self-update --update-keys to set them up
</span></span></code></pre></div><p><strong>Il vous dit quoi faire</strong> !!!</p>
<p>Donc :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ composer self-update --update-keys
</span></span><span style="display:flex;"><span>Open https://composer.github.io/pubkeys.html to find the latest keys
</span></span><span style="display:flex;"><span>Enter Dev / Snapshot Public Key <span style="color:#5bc4bf">(</span>including lines with -----<span style="color:#5bc4bf">)</span>:
</span></span></code></pre></div><p>Là, le shell reste en attente jusqu&rsquo;à ce que vous lui <strong>copiez la clé demandée</strong>,
que vous trouverez sur <a href="https://composer.github.io/pubkeys.html" rel="external">https://composer.github.io/pubkeys.html</a>, puisqu&rsquo;il
a même la gentillesse de vous le dire !</p>
<p>Il vous demande de rentrer dans un premier temps, la clé <code>Dev / Snapshot Public</code>,
puis une fois validée, vous demandera d&rsquo;intégrer la clé <code>Tags Public</code>. <br>
Et pour finir vous dira dans quel répertoire personnel, elles seront enregistrées.</p>
<p>Si l&rsquo;entrée saisie n&rsquo;est pas correcte, vous aurez un message d&rsquo;erreur : <code>Invalid input</code>,
il vous sera redemandé de faire la saisie !</p>
<h3 id="error-curl-version-missing">Error: curl version: missing…</h3>
<p>Si le test se plaint que la version de curl est manquante, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>curl version: missing, using php streams fallback, which reduces performance
</span></span></code></pre></div><p>Vérifiez si vous avez installé le paquet <code>php-curl</code> correspondant à votre version
de PHP, et que vous avez bien lié le binaire dans le répertoire correspondant à
votre version de PHP, tel que <em>(par exemple)</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>doas ln -sf /etc/php-8.2.sample/curl.ini /etc/php-8.2/; <span style="color:#815ba4">done</span>
</span></span></code></pre></div><p>Puis relancez le diagnostic ;)</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment installer configurer PHP Composer sous OpenBSD]]></summary>
        <published>2019-05-27T17:24:38+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5f7f4473-c49f-be9c-6629-878b00a2a3b7</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/developpez.net/dive-into-python-6-closures-et-generateurs/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Dive Into Python 3 - 6 : Closures et Générateurs</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <content type="html"><![CDATA[<h1 id="chapitre-6--closures-et-générateurs">Chapitre 6 : Closures et Générateurs</h1>
<blockquote>
<p>&ldquo;My spelling is Wobbly. It’s good spelling but it Wobbles, and the letters get in the wrong places.&rdquo; — Winnie-the-Pooh</p>
</blockquote>
<h2 id="en-plongée">En plongée</h2>
<p>Ayant grandit en fils de bibliothécaire et de spécialiste en langue anglaise, j&rsquo;ai toujours été fasciné par les langages. Pas les langages de programmation. Enfin si, les langages de programmation, mais aussi les langages naturels. Prenez l&rsquo;anglais. L&rsquo;anglais est un langage schizophrénique qui emprunte des mots de l&rsquo;allemand, du français, de l’espagnol et du latin (pour en citer quelque uns). En fait, &ldquo;emprunte&rdquo; n&rsquo;est pas le bon mot ; &ldquo;pille&rdquo; est plus approprié. Ou peut être, &ldquo;assimile&rdquo; — comme les Borgs. Ouais, j&rsquo;aime ça.</p>
<blockquote>
<p>Nous sommes les Borgs. Vos caractèristiques linguistiques et étymologiques seront ajoutées aux nôtres. La résistance est futile.</p>
</blockquote>
<p>Dans ce chapitre, vous allez apprendre les noms pluriels. Mais aussi, les fonctions qui retournent d&rsquo;autres fonctions, les expressions régulières avancées, et les générateurs. Mais d&rsquo;abord, discutons de comment former les noms pluriels. (Si vous n&rsquo;avez pas encore lu <a>le chapitre sur les expressions régulières</a>, maintenant serait le bon moment. Ce chapitre assume que vous comprenez les bases des expressions régulières, et il en vient rapidement à des usages plus avancés.)</p>
<p>Si vous avez grandit dans un pays anglophone ou apprit l&rsquo;anglais dans un contexte scolaire, vous êtes probablement familier avec les règles de base :</p>
<ul>
<li>Si un mot se termine avec un S, X, ou Z, ajoutez ES. <em>Bass</em> devient <em>basses</em>, <em>fax</em> devient <em>faxes</em>, et <em>waltz</em> devient <em>waltzes</em>.</li>
<li>Si un mot se termine avec un H sonore, ajoutez ES ; s&rsquo;il se termine avec un H muet, ajoutez juste un S. Qu&rsquo;est-ce qu&rsquo;un H sonore ? C&rsquo;est un H qui combiné avec d&rsquo;autres lettres forme un son que vous pouvez entendre. Donc <em>coach</em> devient <em>coaches</em> et <em>rash</em> devient <em>rashes</em>, parce que vous pouvez entendre les sons CH et SH quand vous les prononcez. Mais <em>cheetah</em> devient <em>cheetahs</em>, parce que le H est muet.</li>
<li>Si un mot se termine avec un Y qui sonne comme in I, remplacez le Y par IES ; si le Y est combiné avec une voyelle pour sonner différemment, ajoutez juste un S. Donc <em>vacancy</em> devient <em>vacancies</em>, mais <em>day</em> devient <em>days</em>.</li>
<li>Si tout échoue, alors ajoutez simplement S et espérez que ça ira.</li>
</ul>
<p>(Je sais, il y a plein d&rsquo;exceptions. <em>Man</em> devient <em>men</em> et <em>woman</em> devient <em>women</em>, mais <em>human</em> devient <em>humans</em>. <em>Mouse</em> devient <em>mice</em> and <em>louse</em> devient <em>lice</em>, mais <em>house</em> devient <em>houses</em>. <em>Knife</em> devient <em>knives</em> et <em>wife</em> devient <em>wives</em>, mais <em>lowlife</em> devient <em>lowlifes</em>. Et ne parlons même pas des mots qui sont leur propre pluriel comme <em>sheep</em>, <em>deer</em> et <em>haiku</em>.)</p>
<p>Bien évidemment, les autres langues sont complètement différentes.</p>
<p>Développons une librairie Python qui forme automatiquement le pluriel des mots anglais. Nous commencerons seulement avec ces quatre règles, mais gardez à l&rsquo;esprit que vous allez inévitablement en ajouter d&rsquo;autres.</p>
<h2 id="je-sais-utilisons-les-expression-régulières-">Je sais, utilisons les expression régulières !</h2>
<p>Dons vous recherchez des mots qui, au moins en anglais, signifie que vous recherchez des chaînes de caractères. Vous avez des règles qui disent que vous devez trouver différentes combinaisons de caractères, et leur faire différentes choses. Cela semble être un boulot pour les expressions régulières !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun):          
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[sxz]$&#39;</span>, noun):             <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)        <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">elif</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeioudgkprt]h$&#39;</span>, noun):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)       
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">elif</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, noun):      
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>, noun)     
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> noun <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;s&#39;</span>
</span></span></code></pre></div><p>(1) C&rsquo;est une expression régulière, mais elle utilise une syntaxe que vous n&rsquo;avez pas vu dans le chapitre <a><em>Expressions Régulières</em></a>. Les crochets signifient &ldquo;correspond exactement à un de ces caractères&rdquo;. Donc <code>[sxz]</code> signifie &quot; <code>s</code>, ou <code>x</code>, ou <code>z</code> &ldquo;, mais seulement à un d&rsquo;entre eux. Le <code>$</code> devrait être familier ; il correspond à la fin de chaîne. Combinés, cette expression régulière vérifie si <code>noun</code> se termine avec <code>s</code>, <code>x</code> ou <code>z</code>.</p>
<p>(2) Cette fonction <code>re.sub()</code> exécute une substitution de chaînes par expression régulière.</p>
<p>Regardons les substitutions par expression régulière plus en détail.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[abc]&#39;</span>, <span style="color:#48b685">&#39;Mark&#39;</span>)    <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span>_sre<span style="color:#5bc4bf">.</span>SRE_Match object at <span style="color:#f99b15">0x001C1FA8</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;[abc]&#39;</span>, <span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;Mark&#39;</span>)  <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Mork&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;[abc]&#39;</span>, <span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;rock&#39;</span>)  <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;rook&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;[abc]&#39;</span>, <span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;caps&#39;</span>)  <span style="color:#776e71">### (4)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;oops&#39;</span>
</span></span></code></pre></div><p>(1) Est-ce que la chaîne <code>Mark</code> contient <code>a</code>, <code>b</code>, ou <code>c</code> ? Oui, elle contient <code>a</code>.</p>
<p>(2) OK, maintenant trouvons <code>a</code>, <code>b</code>, ou <code>c</code>, et replaçons-le par <code>o</code>. <code>Mark</code> devient <code>Mork</code>.</p>
<p>(3) La même fonction transforme <code>rock</code> en <code>rook</code>.</p>
<p>(4) Vous devez penser que cela devrait transformer <code>caps</code> en <code>oaps</code>, mais en fait non. <code>re.sub</code> remplace <em>toutes</em> les correspondances, pas seulement la première. Donc cette expression régulière transforme <code>caps</code> en <code>oops</code>, parce que le <code>c</code> et le <code>a</code> sont tous les deux transformés en <code>o</code>.</p>
<p>Et maintenant, revenons à la fonction <code>plural()</code>…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun):          
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[sxz]$&#39;</span>, noun):            
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)         <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">elif</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeioudgkprt]h$&#39;</span>, noun):  <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">elif</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, noun):        <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>, noun)     
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> noun <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;s&#39;</span>
</span></span></code></pre></div><p>(1) Ici, vous remplacez la fin de chaîne (correspondant à <code>$</code>) par la chaîne <code>es</code>. En d&rsquo;autres mots, cela ajoute <code>es</code> à la chaîne. Vous pouvez obtenir la même chose avec la concaténation de chaîne, par exemple <code>noun + 'es'</code>, mais j&rsquo;ai choisi d&rsquo;utiliser les expressions régulières pour chaque règle, pour des raisons qui deviendront plus claires plus loin dans ce chapitre.</p>
<p>(2) Regardez attentivement, c&rsquo;est une autre nouvelle variation. Le <code>^</code>, en premier caractère entre crochets, signifie quelque chose de spécial : la négation. <code>[^abc]</code> signifie &ldquo;n&rsquo;importe quel caractère <em>sauf</em> <code>a</code>, <code>b</code>, ou <code>c</code>&rdquo;. Donc <code>[^aeioudgkprt]</code> signifie n&rsquo;importe quel caractère sauf <code>a</code>, <code>e</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>d</code>, <code>g</code>, <code>k</code>, <code>p</code>, <code>r</code>, ou <code>t</code>. Puis ce caractère doit être suivi par <code>h</code>, suivi par la fin de chaîne. Vous cherchez les mots qui finissent avec un H où le H est sonore.</p>
<p>(3) Même motif ici : trouver les mots qui se terminent par Y, où le caractère avant le Y n&rsquo;est <em>pas</em> <code>a</code>, <code>e</code>, <code>i</code>, <code>o</code>, ou <code>u</code>. Vous cherchez les mots qui finissent avec un Y qui sonne comme un I.</p>
<p>Regardons la négation d&rsquo;expression régulière plus en détail.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, <span style="color:#48b685">&#39;vacancy&#39;</span>)  <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span>_sre<span style="color:#5bc4bf">.</span>SRE_Match object at <span style="color:#f99b15">0x001C1FA8</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, <span style="color:#48b685">&#39;boy&#39;</span>)      <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, <span style="color:#48b685">&#39;day&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, <span style="color:#48b685">&#39;pita&#39;</span>)     <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> 
</span></span></code></pre></div><p>(1) <code>vacancy</code> correspond à cette expression régulière, parce qu&rsquo;il se termine en <code>cy</code>, et <code>c</code> n&rsquo;est pas <code>a</code>, <code>e</code>, <code>i</code>, <code>o</code>, ou <code>u</code>.</p>
<p>(2) <code>boy</code> ne correspond pas, parce qu&rsquo;il se termine en <code>oy</code>, et vous avez spécifiquement dit que le caractère avant le <code>y</code> ne peut pas être <code>o</code>. <code>day</code> ne correspond pas, parce qu&rsquo;il se termine en <code>ay</code>.</p>
<p>(3) <code>pita</code> ne correspond pas, parce qu&rsquo;il ne se termine pas en <code>y</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>, <span style="color:#48b685">&#39;vacancy&#39;</span>)               <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;vacancies&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>, <span style="color:#48b685">&#39;agency&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;agencies&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;([^aeiou])y$&#39;</span>, <span style="color:#48b685">r</span><span style="color:#48b685">&#39;\1ies&#39;</span>, <span style="color:#48b685">&#39;vacancy&#39;</span>)  <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;vacancies&#39;</span>
</span></span></code></pre></div><p>(1) Cette expression régulière transforme <code>vacancy</code> en <code>vacancies</code> et <code>agency</code> en <code>agencies</code>, ce qui est ce que vous voulez. Notez que cela transforme aussi <code>boy</code> en <code>boies</code>, mais cela n&rsquo;arrivera jamais dans la fonction parce que vous avez fait cette recherche d&rsquo;abord avec <code>re.search</code> pour savoir si vous devez la faire avec <code>re.sub</code>.</p>
<p>(2) Juste en passant, je voudrais pointer le fait qu&rsquo;il est possible de combiner ces deux expressions régulières (une pour trouver si la règle s&rsquo;applique, et une autre pour effectivement l&rsquo;appliquer) en une unique expression régulière. Cela ressemblerait à ça. Cela doit sembler en grande partie familier : vous utilisez un groupe de capture, que vous avez appris dans l’<a>Étude de Cas :  Analyser les Numéros de Téléphone</a>. Le groupe est utilisé pour capturer le caractère avant la lettre <code>y</code>. Puis dans la chaîne de substitution, vous utilisez une nouvelle syntaxe, <code>\1</code>, qui signifie « hé, tu te souviens de ce premier groupe ? met le ici. » Dans ce cas, vous capturez le <code>c</code> avant le <code>y</code> ; quand vous faite la substitution, vous substituez <code>c</code> à la place de <code>c</code>, et <code>ies</code> à la place de <code>y</code>. (Si vous avez plus d&rsquo;un groupe de capture, vous pouvez utiliser <code>\2</code> et <code>\3</code> et ainsi de suite.)</p>
<p>Les substitutions par expression régulière sont extrêmement puissantes, et la syntaxe <code>\1</code> les rend encore plus puissante. Mais combiner toute l’opération en une seule expression régulière est aussi plus difficile à lire, et cela ne correspond pas directement à la façon dont vous décrivez les règles du pluriel. Vous avez initialement posé les règles comme &ldquo;si le mot se termine en S, X, ou Z, alors ajouter ES&rdquo;. Si vous regardez cette fonction, vous avez deux lignes de code qui disent &ldquo;si le mot se termine en S, X, ou Z, alors ajouter ES&rdquo;. Il n&rsquo;est pas possible d&rsquo;être plus direct.</p>
<h2 id="une-liste-de-fonctions">Une liste de fonctions</h2>
<p>Maintenant, vous allez ajouter un niveau d&rsquo;abstraction. Vous avez commencé par définir une liste de règles : si ceci, faire cela, autrement aller à la prochaine règle. Compliquons temporairement une partie du programme, ainsi vous pourrez en simplifier une autre partie.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">match_sxz</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[sxz]$&#39;</span>, noun)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_sxz</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">match_h</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeioudgkprt]h$&#39;</span>, noun)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_h</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;$&#39;</span>, <span style="color:#48b685">&#39;es&#39;</span>, noun)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">match_y</span>(noun):                             <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>search(<span style="color:#48b685">&#39;[^aeiou]y$&#39;</span>, noun)
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_y</span>(noun):                             <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(<span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>, noun)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">match_default</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#815ba4">True</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_default</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> noun <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;s&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>rules <span style="color:#5bc4bf">=</span> ((match_sxz, apply_sxz),               <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>         (match_h, apply_h),
</span></span><span style="display:flex;"><span>         (match_y, apply_y),
</span></span><span style="display:flex;"><span>         (match_default, apply_default)
</span></span><span style="display:flex;"><span>         )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun):           
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> matches_rule, apply_rule <span style="color:#5bc4bf">in</span> rules:     <span style="color:#776e71">### (4)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> matches_rule(noun):
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> apply_rule(noun)
</span></span></code></pre></div><p>(1) Maintenant, chaque règle de correspondance est sa propre fonction qui retourne les résultats de l&rsquo;appel de la fonction <code>re.search()</code>.</p>
<p>(2) Chaque règle d&rsquo;application est aussi sa propre fonction qui appelle la fonction <code>re.sub()</code> pour appliquer la règle de pluriel appropriée.</p>
<p>(3) Au lieu d&rsquo;avoir une fonction (<code>plural()</code>) avec de multiple règles, vous avez la structure de données <code>rules</code> qui  est une séquence de paires de fonctions.</p>
<p>(4) Puisque les règles ont été placées dans une structure de données séparée, la nouvelle fonction <code>plural()</code> peut être réduite à quelques lignes de code. En utilisant une boucle <code>for</code>, vous pouvez extraire les règles de correspondance et les règles d&rsquo;application deux à la fois (une de correspondance et une d&rsquo;application) de la structure <code>rules</code>. À la première itération de la boucle <code>for</code>, <code>matches_rule</code> recevra <code>match_sxz</code>, et <code>apply_rule</code> recevra <code>apply_sxz</code>. À la seconde itération (en présumant que vous arrivez jusque là), <code>matches_rules</code> sera assignée à <code>match_h</code>, et <code>apply_rule</code> sera assignée à <code>apply_h</code>. La fonction est garantie de retourner quelque chose éventuellement, parce que la dernière règle (<code>match_default</code>) retourne simplement <code>True</code>, cela signifie que la règle d&rsquo;application correspondante (<code>apply_default</code>) sera toujours appliquée.</p>
<p>La raison pour laquelle cette technique fonctionne est que <a>tout en Python est un objet</a>, y compris les fonctions. La structure de données <code>rules</code> contient des fonctions — pas des noms de fonctions, mais de vrais objets fonction. Quand ils sont assignés dans la boucle <code>for</code>, alors <code>matches_rule</code> et <code>apply_rule</code> sont de vraies fonctions que vous pouvez appeler. À la première itération de la boucle <code>for</code>, c&rsquo;est équivalent à appeler <code>matches_sxz(noun)</code>, et si elle retourne une correspondance, à appeler <code>apply_sxz(noun)</code>.</p>
<p>Si cet additionnel niveau d&rsquo;abstraction prête à confusion, essayez de dérouler la fonction pour voir l’équivalence. La boucle <code>for</code> complète est équivalente à :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> match_sxz(noun):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> apply_sxz(noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> match_h(noun):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> apply_h(noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> match_y(noun):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> apply_y(noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> match_default(noun):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> apply_default(noun)
</span></span></code></pre></div><p>Le bénéfice ici est que la fonction <code>plural()</code> est maintenant simplifiée. Elle prend une séquence de règles, définies quelque part, et les itére d&rsquo;une manière générique.</p>
<ol>
<li>Trouver une règle de correspondance.</li>
<li>Une correspondance ? Alors appeler la règle d&rsquo;application et retourner le résultat.</li>
<li>Pas de correspondance ? Aller a l’étape 1.</li>
</ol>
<p>Les règles peuvent être définies n&rsquo;importe où, de n&rsquo;importe quelle façon. La fonction <code>plural()</code> ne s&rsquo;en préoccupe pas.</p>
<p>Maintenant, est-ce qu&rsquo;ajouter ce niveau d&rsquo;abstraction en valait la peine ? Et bien, pas encore. Considérez ce qu&rsquo;il faudrait pour ajouter une nouvelle règle à la fonction. Dans le premier exemple, cela nécessiterait d&rsquo;ajouter une instruction <code>if</code> à la fonction <code>plural()</code>. Dans le second exemple, cela nécessiterait d&rsquo;ajouter deux fonctions, <code>match_foo()</code> et <code>apply_foo()</code>, et puis mettre à jour la séquence <code>rules</code> pour spécifier où dans la séquence les nouvelles fonctions de correspondance et d&rsquo;application doivent être appelées par rapport aux autres règles.</p>
<p>Mais ce n&rsquo;est qu&rsquo;une étape dans la prochaine section. Allons-y…</p>
<h2 id="une-liste-de-motifs">Une liste de motifs</h2>
<p>Définir des fonctions nommées séparées pour chaque règle de correspondance et d&rsquo;application n&rsquo;est pas vraiment nécessaire. Vous ne les appelez jamais directement ; vous les ajoutez à la séquence <code>rules</code> et les appelez depuis-là. De plus, chaque fonction suit l’un des deux motifs. Toutes les fonctions de correspondances appelent <code>re.search()</code> et toutes les fonctions d&rsquo;applications appelent <code>re.sub()</code>. Examinons les motifs afin de définir de nouvelles règles plus faciles :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">build_match_and_apply_functions</span>(pattern, search, replace):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">matches_rule</span>(word):                                     <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>search(pattern, word)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_rule</span>(word):                                       <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(search, replace, word)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> (matches_rule, apply_rule)                           <span style="color:#776e71">### (3)</span>
</span></span></code></pre></div><p>(1) <code>build_match_and_apply_functions()</code> est une fonction qui construit d&rsquo;autres fonction de manière dynamique. Elle prend <code>pattern</code>, <code>search</code> et <code>replace</code>, puis définit une fonction <code>matches_rule()</code> qui appelle <code>re.search()</code> avec le <code>pattern</code> (motif) qui a été passé à la fonction <code>build_match_and_apply_functions()</code>, et (le mot) <code>word</code> qui a été passé à la fonction <code>matches_rule()</code> que vous construisez. Waouh.</p>
<p>(2) Construire la fonction d&rsquo;application fonctionne de la même manière. La fonction d&rsquo;application est une fonction qui prend un paramètre, et qui appelle <code>re.sub()</code> avec les paramètres <code>search</code> et <code>replace</code> qui ont été passés à la fonction <code>build_match_and_apply_functions()</code>, et (le mot) <code>word</code> qui a été passé à la fonction <code>apply_rule()</code> que vous construisez. Cette technique utilisant les valeurs de paramètres externes au sein d&rsquo;une fonction dynamique est appelée <em>closures</em>. Vous définissez essentiellement des constantes au sein de la fonction d&rsquo;application que vous construisez : elle prend un paramètre (<code>word</code>), mais elle le traite alors avec deux autres valeurs (<code>search</code> et <code>replace</code>) qui ont été paramétrées quand vous avez défini la fonction application.</p>
<p>(3) Finalement, la fonction <code>build_match_and_apply_functions()</code> retourne un tuple de deux valeurs : les deux fonctions que vous venez de créer. Les constantes que vous avez définies dans ces fonctions (<code>pattern</code> dans la fonction <code>matches_rule()</code>, et <code>search</code> dans la fonction <code>apply_rule()</code>) restent avec ces fonctions, même après que votre retour de <code>build_match_and_apply_functions()</code>. C&rsquo;est incroyablement cool.</p>
<p>Si cela prête vraiment à confusion (et cela devrait l&rsquo;être, c&rsquo;est bizarre), cela peut devenir plus clair en analysant comment l&rsquo;utiliser.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>patterns <span style="color:#5bc4bf">=</span> \                                                        <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>  (
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;[sxz]$&#39;</span>,           <span style="color:#48b685">&#39;$&#39;</span>,  <span style="color:#48b685">&#39;es&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;[^aeioudgkprt]h$&#39;</span>, <span style="color:#48b685">&#39;$&#39;</span>,  <span style="color:#48b685">&#39;es&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;(qu|[^aeiou])y$&#39;</span>,  <span style="color:#48b685">&#39;y$&#39;</span>, <span style="color:#48b685">&#39;ies&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;$&#39;</span>,                <span style="color:#48b685">&#39;$&#39;</span>,  <span style="color:#48b685">&#39;s&#39;</span>)                                 <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>  )
</span></span><span style="display:flex;"><span>rules <span style="color:#5bc4bf">=</span> [build_match_and_apply_functions(pattern, search, replace)  <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">for</span> (pattern, search, replace) <span style="color:#5bc4bf">in</span> patterns]
</span></span></code></pre></div><p>(1) Nos &ldquo;règles&rdquo; du pluriel sont maintenant définies comme tuple de tuples de chaînes (non pas de fonctions). La première chaîne dans chaque groupe est le motif d&rsquo;expression régulière que vous utiliseriez avec <code>re.search()</code> pour voir si la règle correspond. La deuxième et la troisième chaîne dans chaque groupe sont les expressions de recherche et de remplacement que vous utiliseriez avec <code>re.sub()</code> pour effectivement appliquer la règle afin de transformer un nom en son pluriel.</p>
<p>(2) Il y a un léger changement ici, dans la règle par défaut. Dans l&rsquo;exemple précédent, la fonction <code>match_default()</code> retournait simplement <code>True</code>, signifiant que si aucune des règles spécifiques ne correspond, le code ajouterait simplement un <code>s</code> à la fin du mot donné. Cette exemple fait quelque chose de fonctionnellement équivalent. La dernière expression régulière demande si le mot a une fin (<code>$</code> correspond à la fin d&rsquo;une chaîne). Bien sur, chaque chaîne a une fin, même une chaîne vide, donc cette expression correspond toujours. Ainsi, elle sert le même objectif que la fonction <code>matches_default()</code> qui retournait toujours <code>True</code> : elle assure que si aucune règle spécifique ne correspond, le code ajoute un <code>s</code> à la fin du mot donné.</p>
<p>(3) Cette ligne est magique. Elle prend la séquence de chaînes dans <code>patterns</code> et les transforme en une séquence de fonctions. Comment ? En faisant correspondre les chaînes à la fonction <code>build_match_and_apply_functions()</code>. C&rsquo;est-à-dire, elle prend chaque triplet de chaînes et appelle la fonction <code>build_match_and_apply_functions()</code> avec ces trois chaînes comme arguments. La fonction <code>build_match_and_apply_functions()</code> retourne un tuple de deux fonctions. Cela signifie que <code>rules</code> est donc fonctionnellement équivalente à l&rsquo;exemple précédent : une liste de tuples où chaque tuple est une paire de fonctions. La première fonction est la fonction de correspondance qui appelle <code>re.search()</code>, et la seconde fonction est la fonction d&rsquo;application qui appelle <code>re.sub()</code>.</p>
<p>Cette version du script est complétée par le point d’entrée principal, la fonction <code>plural()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> matches_rule, apply_rule <span style="color:#5bc4bf">in</span> rules:  <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> matches_rule(noun):
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> apply_rule(noun)
</span></span></code></pre></div><p>(1) Puisque la liste <code>rules</code> est la même que dans l&rsquo;exemple précédent (c&rsquo;est vraiment le cas), cela ne devrait pas être surprenant que la fonction <code>plural()</code> n&rsquo;a pas changé du tout. Elle est complètement générique ; elle prend une liste de fonctions de règle et les appelle dans l&rsquo;ordre. Elle ne se soucie pas de comment les règles sont définies. Dans l&rsquo;exemple précédent, elles étaient définies comme des fonctions nommées séparées. Maintenant, elles sont construites dynamiquement en faisant correspondre la sortie de la fonction <code>build_match_and_apply_functions()</code> avec une liste brute de chaînes. Cela n&rsquo;a aucune d&rsquo;importance ; la fonction <code>plural()</code> fonctionne toujours de la même façon.</p>
<h2 id="un-fichier-de-motifs">Un fichier de motifs</h2>
<p>Vous avez extrait tout le code dupliqué et ajoutez assez d&rsquo;abstraction pour les que les règles du pluriel soient définies dans une liste de chaînes. La prochaine étape logique est de prendre ces chaînes et de les mettre dans un fichier séparé, où elles peuvent être maintenues séparément du code qui les utilise.</p>
<p>En premier, créons un fichier texte qui contient les règles que vous voulez. Pas de structure de données sophistiquée, juste des chaînes délimitées par des espaces dans trois colonnes. Appelons-le <code>plural4-rules.txt</code>.</p>
<pre tabindex="0"><code>[sxz]$               $    es
[^aeioudgkprt]h$     $    es
[^aeiou]y$          y$    ies
$                    $    s
</code></pre><p>Maintenant regardons comment nous pouvons utiliser ce fichier de règles.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">build_match_and_apply_functions</span>(pattern, search, replace):     <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">matches_rule</span>(word):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>search(pattern, word)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">apply_rule</span>(word):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> re<span style="color:#5bc4bf">.</span>sub(search, replace, word)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> (matches_rule, apply_rule)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>rules <span style="color:#5bc4bf">=</span> []
</span></span><span style="display:flex;"><span><span style="color:#815ba4">with</span> open(<span style="color:#48b685">&#39;plural4-rules.txt&#39;</span>, encoding<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;utf-8&#39;</span>) <span style="color:#815ba4">as</span> pattern_file:  <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> line <span style="color:#5bc4bf">in</span> pattern_file:                                      <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>        pattern, search, replace <span style="color:#5bc4bf">=</span> line<span style="color:#5bc4bf">.</span>split(<span style="color:#815ba4">None</span>, <span style="color:#f99b15">3</span>)             <span style="color:#776e71">### (4)</span>
</span></span><span style="display:flex;"><span>        rules<span style="color:#5bc4bf">.</span>append(build_match_and_apply_functions(              <span style="color:#776e71">### (5)</span>
</span></span><span style="display:flex;"><span>                pattern, search, replace))
</span></span></code></pre></div><p>(1) La fonction <code>build_match_and_apply_functions()</code> n&rsquo;a pas changé. Vous utilisez toujours des closures pour construire deux fonctions dynamiquement qui utilisent les variables définies dans la fonction externe.</p>
<p>(2) La fonction globale <code>open()</code> ouvre un fichier et retourne un objet fichier. Dans ce cas, le fichier que nous ouvrons contient les motifs de chaînes pour mettre au pluriel des noms. L&rsquo;instruction <code>with</code> crée ce qui est appelé un <em>contexte</em> : quand le bloc <code>with</code> se termine, Python va automatiquement fermer le fichier, même si une exception se produit à l’intérieur du bloc <code>with</code>. Vous en apprendrez plus à-propos des blocs <code>with</code> et des objets fichier dans le chapitre <a>Fichiers</a>.</p>
<p>(3) L&rsquo;idiome <code>for line in &lt;fileobject&gt;</code> lit les données depuis le fichier ouvert, une ligne à la fois, et assigne le texte à la variable <code>line</code>. Vous en apprendrez plus à-propos de la lecture de fichier dans le chapitre  <a>Fichiers</a>.</p>
<p>(4) Chaque ligne du fichier a en fait trois valeurs, mais elles sont séparées par des espaces blancs (tabulation ou espace, cela n&rsquo;a pas d&rsquo;importance). Pour les séparer, utilisez la méthode de chaîne <code>split()</code>. Le premier argument de la méthode <code>split()</code> est <code>None</code>, ce qui signifie &ldquo;découpe à chaque espace blanc (tabulation ou espace, cela n&rsquo;a pas d&rsquo;importance).&rdquo; Le second argument est <code>3</code>, ce qui signifie &ldquo;découpe sur les espaces blancs 3 fois, puis laisse en l’état le reste de la ligne.&rdquo; Une ligne comme <code>[sxz]$ $ es</code> sera découpée en liste <code>['[sxz]$', '$', 'es']</code>, ce qui signifie que <code>pattern</code> aura &lsquo;<code>[sxz]$</code>&rsquo;, <code>search</code> aura &lsquo;<code>$</code>&rsquo;, et <code>replace</code> aura &lsquo;<code>es</code>&rsquo;. C&rsquo;est beaucoup de puissance dans une seule petite ligne de code.</p>
<p>(5) Finalement, vous passez <code>pattern</code>, <code>search</code>, et <code>replace</code> à la fonction <code>build_match_and_apply_functions()</code>, qui retourne un tuple de fonctions. Vous ajouter ce tuple à la liste <code>rules</code>, et <code>rules</code> finit par stocker la liste des fonctions de correspondance et d&rsquo;application que la fonction <code>plural()</code> attend.</p>
<p>L’amélioration ici est que vous avez complètement séparé les règles du pluriel dans une fichier externe, ainsi il peut être maintenu séparément du code qui l&rsquo;utilise. Le code avec le code, les données avec  les données, et tout va bien.</p>
<h2 id="générateurs">Générateurs</h2>
<p>Est-ce que ce ne serait pas grandiose d&rsquo;avoir une fonction générique <code>plural()</code> qui analyse le fichier de règles ? Récupère les règles, cherche une correspondance, applique la transformation appropriée, va à la règle suivante. C&rsquo;est tout ce que la fonction <code>plural()</code> a à faire, et c&rsquo;est tout ce que la fonction <code>plural()</code> devrait faire.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">rules</span>(rules_filename):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">with</span> open(rules_filename, encoding<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;utf-8&#39;</span>) <span style="color:#815ba4">as</span> pattern_file:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">for</span> line <span style="color:#5bc4bf">in</span> pattern_file:
</span></span><span style="display:flex;"><span>            pattern, search, replace <span style="color:#5bc4bf">=</span> line<span style="color:#5bc4bf">.</span>split(<span style="color:#815ba4">None</span>, <span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">yield</span> build_match_and_apply_functions(pattern, search, replace)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun, rules_filename<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;plural5-rules.txt&#39;</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> matches_rule, apply_rule <span style="color:#5bc4bf">in</span> rules(rules_filename):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> matches_rule(noun):
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> apply_rule(noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">raise</span> <span style="color:#ef6155">ValueError</span>(<span style="color:#48b685">&#39;no matching rule for </span><span style="color:#f99b15">{0}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(noun))
</span></span></code></pre></div><p>Mais comment est-ce que <em>ça</em> fonctionne ? Regardons d&rsquo;abord un premier exemple interactif.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">def</span> <span style="color:#06b6ef">make_counter</span>(x):
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     print(<span style="color:#48b685">&#39;entering make_counter&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     <span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>         <span style="color:#815ba4">yield</span> x                    <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>         print(<span style="color:#48b685">&#39;incrementing x&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>         x <span style="color:#5bc4bf">=</span> x <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span> 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> counter <span style="color:#5bc4bf">=</span> make_counter(<span style="color:#f99b15">2</span>)          <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> counter                            <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span>generator object at <span style="color:#f99b15">0x001C9C10</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(counter)                      <span style="color:#776e71">### (4)</span>
</span></span><span style="display:flex;"><span>entering make_counter
</span></span><span style="display:flex;"><span><span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(counter)                      <span style="color:#776e71">### (5)</span>
</span></span><span style="display:flex;"><span>incrementing x
</span></span><span style="display:flex;"><span><span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(counter)                      <span style="color:#776e71">### (6)</span>
</span></span><span style="display:flex;"><span>incrementing x
</span></span><span style="display:flex;"><span><span style="color:#f99b15">4</span>
</span></span></code></pre></div><p>(1) La présence du mot-clef <code>yield</code> dans <code>make_counter</code> signifie que ce n&rsquo;est pas une fonction normale. C&rsquo;est un type spécial de fonction qui génère des valeurs l&rsquo;une après l&rsquo;autre. Vous pouvez l&rsquo;imaginez comme une fonction pouvant être interrompue et reprise. L&rsquo;appeler retournera un <em>générateur</em> qui peut être utiliser pour générer des valeurs successives de <code>x</code>.</p>
<p>(2) Pour créer une instance du générateur <code>make_counter</code>, appelez-le juste comme une autre fonction. Notez qu&rsquo;en fait cela n’exécute pas le code de la fonction. Vous pouvez le voir parce que la première ligne de la fonction <code>make_counter</code> appelle <code>print()</code>, mais rien n&rsquo;est encore affiché.</p>
<p>(3) La fonction <code>make_counter</code> retourne un objet générateur.</p>
<p>(4) La fonction <code>next()</code> prend un objet générateur et retourne sa prochaine valeur. La première fois que vous appelez <code>next()</code> avec le générateur <code>counter</code>, elle exécute le code dans <code>make_counter</code> jusqu&rsquo;à la première instruction <code>yield</code>, puis retourne la valeur qui a été générée. Dans ce cas, ce sera <code>2</code>, car vous avez initialement créé le générateur en appelant <code>make_counter(2)</code>.</p>
<p>(5) Appeler de façon répétitive <code>next()</code> avec le mème objet générateur reprend exactement là où il s&rsquo;était arrêté et continue jusqu&rsquo;à ce qu&rsquo;il rencontre la prochaine instruction <code>yield</code>. Toutes les variables, état local, etc, sont sauvegardées à <code>yield</code> et rétablies à <code>next()</code>. La prochaine ligne de code attendant d’être exécutée appelle <code>print()</code>, qui affiche <code>incrementing x</code>. Après cela, l&rsquo;instruction <code>x = x + 1</code>. Puis elle boucle à nouveau au travers de la boucle <code>while</code>, et la première chose recontrée est l&rsquo;instruction <code>yield x</code>, qui sauvegarde l’état de toute chose et retourne la valeur courante de <code>x</code> (maintenant <code>3</code>).</p>
<p>(6) La deuxième fois que vous appelez <code>next()</code>, vous faites à nouveau les même choses, mais cette fois <code>x</code> vaut <code>4</code>.</p>
<p>Puisque <code>make_counter</code> définit une boucle infinie, vous pouvez théoriquement faire cela pour toujours, et ça continuerait juste d’incrémenter <code>x</code> et de cracher des valeurs. Mais regardons plutôt des utilisations plus productives des générateurs.</p>
<blockquote>
<p><em><strong>“yield” met en pause une fonction. “next()” la reprend où elle s’était interrompue.</strong></em></p>
</blockquote>
<h3 id="un-générateur-fibonacci">Un générateur Fibonacci</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">fib</span>(max):
</span></span><span style="display:flex;"><span>    a, b <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">0</span>, <span style="color:#f99b15">1</span>          <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">while</span> a <span style="color:#5bc4bf">&lt;</span> max:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">yield</span> a          <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>        a, b <span style="color:#5bc4bf">=</span> b, a <span style="color:#5bc4bf">+</span> b  <span style="color:#776e71">### (3)</span>
</span></span></code></pre></div><p>(1) La séquence de Fibonacci est une séquence de nombres où chaque nombre est la somme des deux nombres qui le précèdent. Elle commence avec <code>0</code> et <code>1</code>, progresse doucement d&rsquo;abord, puis de plus en plus rapidement. Pour commencer la séquence, vous avez besoin de deux variables : <code>a</code> commence à <code>0</code>, et <code>b</code> commence à <code>1</code>.</p>
<p>(2) Générons <code>a</code> qui est le nombre courant dans la séquence.</p>
<p>(3) Assignons <code>b</code>, qui est le prochain nombre dans la séquence, à <code>a</code>, mais calculons aussi la prochaine valeur <code>(a + b)</code> et assignons-la à <code>b</code> pour l&rsquo;utiliser plus tard. Notez que cela se produit en parallèle ; si <code>a</code> vaut <code>3</code> et <code>b</code> vaut <code>5</code>, alors <code>a, b = b, a + b</code> paramètrera <code>5</code> à <code>a</code> (la précédente valeur de <code>b</code>) et <code>8</code> à <code>b</code> (la somme des précédentes valeurs de <code>a</code> et <code>b</code>).</p>
<p>Donc vous avez une fonction qui restitue les nombres Fibonacci successifs. Bien sur, vous pouvez faire cela avec la récursion, mais cette manière est plus facile à lire. De même, cela fonctionne bien avec les boucles <code>for</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">from</span> <span style="color:#fec418">fibonacci</span> <span style="color:#5bc4bf">import</span> fib
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">for</span> n <span style="color:#5bc4bf">in</span> fib(<span style="color:#f99b15">1000</span>):      <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     print(n, end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)    <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">0</span> <span style="color:#f99b15">1</span> <span style="color:#f99b15">1</span> <span style="color:#f99b15">2</span> <span style="color:#f99b15">3</span> <span style="color:#f99b15">5</span> <span style="color:#f99b15">8</span> <span style="color:#f99b15">13</span> <span style="color:#f99b15">21</span> <span style="color:#f99b15">34</span> <span style="color:#f99b15">55</span> <span style="color:#f99b15">89</span> <span style="color:#f99b15">144</span> <span style="color:#f99b15">233</span> <span style="color:#f99b15">377</span> <span style="color:#f99b15">610</span> <span style="color:#f99b15">987</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(fib(<span style="color:#f99b15">1000</span>))          <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>[<span style="color:#f99b15">0</span>, <span style="color:#f99b15">1</span>, <span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>, <span style="color:#f99b15">3</span>, <span style="color:#f99b15">5</span>, <span style="color:#f99b15">8</span>, <span style="color:#f99b15">13</span>, <span style="color:#f99b15">21</span>, <span style="color:#f99b15">34</span>, <span style="color:#f99b15">55</span>, <span style="color:#f99b15">89</span>, <span style="color:#f99b15">144</span>, <span style="color:#f99b15">233</span>, <span style="color:#f99b15">377</span>, <span style="color:#f99b15">610</span>, <span style="color:#f99b15">987</span>]
</span></span></code></pre></div><p>(1) Vous pouvez utiliser un générateur tel que <code>fib()</code> directement dans la boucle <code>for</code>. La boucle <code>for</code> appellera automatiquement la fonction <code>next()</code>, récupèrera les valeurs du générateur  <code>fib()</code> et les assignera à la variable d&rsquo;index (<code>n</code>) de la boucle <code>for</code>.</p>
<p>(2) A chaque passage dans la boucle <code>for</code>, <code>n</code> reçoit une nouvelle valeur de l&rsquo;instruction <code>yield</code> dans <code>fib()</code>,  tout ce que vous avez à faire est de l&rsquo;afficher. Une fois que <code>fib()</code> est à court de nombres (<code>a</code> devient plus grand que <code>max</code>, qui dans ce cas vaut <code>1000</code>), alors la boucle <code>for</code> se termine normalement.</p>
<p>(3) C&rsquo;est un idiome utile : passez un générateur à la fonction <code>list()</code>, et il itérera le générateur tout entier (exactement comme la boucle <code>for</code> de l&rsquo;exemple précédent) et retournera une liste de toutes les valeurs.</p>
<h3 id="un-générateur-de-règles-du-pluriel">Un générateur de règles du pluriel</h3>
<p>Retournons à <code>plural5.py</code> et voyons comment cette version de <code>plural()</code> fonctionne.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">rules</span>(rules_filename):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">with</span> open(rules_filename, encoding<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;utf-8&#39;</span>) <span style="color:#815ba4">as</span> pattern_file:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">for</span> line <span style="color:#5bc4bf">in</span> pattern_file:
</span></span><span style="display:flex;"><span>            pattern, search, replace <span style="color:#5bc4bf">=</span> line<span style="color:#5bc4bf">.</span>split(<span style="color:#815ba4">None</span>, <span style="color:#f99b15">3</span>)                   <span style="color:#776e71">### (1)</span>
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">yield</span> build_match_and_apply_functions(pattern, search, replace)  <span style="color:#776e71">### (2)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">plural</span>(noun, rules_filename<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;plural5-rules.txt&#39;</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> matches_rule, apply_rule <span style="color:#5bc4bf">in</span> rules(rules_filename):                   <span style="color:#776e71">### (3)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> matches_rule(noun):
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> apply_rule(noun)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">raise</span> <span style="color:#ef6155">ValueError</span>(<span style="color:#48b685">&#39;no matching rule for </span><span style="color:#f99b15">{0}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(noun))
</span></span></code></pre></div><p>(1) Ici, pas de magie. Souvenez-vous que les lignes du fichier de règles ont trois valeurs séparées par des espaces, donc vous utilisez <code>line.split(None, 3)</code> pour récupérer les trois &ldquo;colonnes&rdquo; et les assigner à trois variables locales.</p>
<p>(2) <em>Et puis vous générez</em>. Qu&rsquo;est-ce que vous générez ? Deux fonctions, construites dynamiquement avec notre vieille amie, <code>build_match_and_apply_functions()</code>, qui est identique à celle des exemples précédents. En d&rsquo;autres mots, <code>rules()</code> est un générateur qui crache des fonctions de correspondance et d&rsquo;application <em>à la demande</em>.</p>
<p>(3) Puisque <code>rules()</code> est un générateur, vous pouvez l&rsquo;utiliser directement dans une boucle <code>for</code>. Au premier passage dans la boucle <code>for</code>, vous appellerez la fonction <code>rules()</code>, qui ouvrira le fichier de motifs, lira la première ligne, construira dynamiquement une fonction de correspondance et une fonction d&rsquo;application à partir des motifs de cette ligne, et générera les fonctions construites dynamiquement. Au second passage dans la boucle <code>for</code>, vous reprendrez exactement là où vous avez laissé <code>rules()</code> (qui était au milieu de la boucle <code>for line in pattern_file</code>). La première chose qu&rsquo;elle fera sera de lire la ligne suivante du fichier (qui est toujours ouvert), de construire dynamiquement une autre fonction de correspondance et une autre fonction d&rsquo;application sur la base des motifs de cette ligne, et générera les deux fonctions.</p>
<p>Qu&rsquo;avez-vous gagné par rapport à l’étape 4 ? Le temps de démarrage. À l’étape 4, quand vous importez le module <code>plural4</code>, il lit tout le fichier de motifs et construit une liste de toutes les règles possibles, avant mème que ne vous pensiez à appeler la fonction <code>plural()</code>. Avec les générateurs, vous pouvez tout faire de façon paresseuse : vous lisez la première règle et créez les fonctions puis les testez, et si ça fonctionne vous ne lisez même pas le reste du fichier ou créez d&rsquo;autres fonctions.</p>
<p>Qu&rsquo;avez-vous perdu ? De la performance ! Chaque fois que vous appelez la fonction <code>plural()</code>, le générateur <code>rules</code> recommence depuis le début — ce qui signifie ouvrir à nouveau le fichier de motifs et le lire depuis le début, une ligne à la fois.</p>
<p>Et si vous pouviez avoir le meilleur des deux mondes : temps de démarrage minimal (ne pas exécuter de code à <code>import</code>), <em>et</em> performance maximale (ne pas construire les même fonctions encore et encore). Oh, et vous voulez toujours garder les règles dans un fichier séparé (parce que le code avec le code et les données avec les données), tant que vous n&rsquo;avez jamais besoin de lire deux fois la même ligne.</p>
<p>Pour faire cela, vous allez devoir construire votre propre itérateur. Mais avant que vous fassiez <em>cela</em>, vous devez apprendre les classes Python.</p>
<h2 id="pour-aller-plus-loin-en-anglais">Pour aller plus loin (en anglais)</h2>
<ul>
<li><a href="https://www.python.org/dev/peps/pep-0255/" rel="external">PEP 255: Simple Generators</a></li>
<li><a href="http://effbot.org/zone/python-with-statement.htm" rel="external">Understanding Python’s “with” statement</a></li>
<li><a href="http://ynniv.com/blog/2007/08/closures-in-python.html" rel="external">Closures in Python</a></li>
<li><a href="https://en.wikipedia.org/wiki/Fibonacci_number" rel="external">Fibonacci numbers</a></li>
</ul>
]]></content>
        <summary type="html"><![CDATA[Relecture du chapitre 6 - Dive into Python pour la communauté DVP]]></summary>
        <published>2019-05-20T11:00:01+01:00</published>
        <updated>2019-05-26T18:15:01+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:aacef81b-80fa-a2ee-cf08-b082898b5159</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/developpez.net/pymotw3-structures-de-donnees/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Python 3 Module of the Week - Chap 2 : Data Structures </title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <content type="html"><![CDATA[<h1 id="structures-de-données">Structures de Données</h1>
<p>Python inclut de nombreuses normes de programmation des structures de données, telles que <code>list</code>, <code>tuple</code>, <code>dict</code>, et <code>set</code>, dans le cadre de ses types natifs. Beaucoup d&rsquo;application ne requièrent pas d&rsquo;autres structures, mais quand elles le font, la bibliothèque standard fournit des versions puissantes et bien testées, prêtes à être utilisées.</p>
<p>Le module <a><code>enum</code></a> fournit une implémentation du type <em>enumeration</em> qui a des capacités d&rsquo;itération et de comparaison. Il peut être utilisé pour créer des symboles bien définis pour les valeurs, à la place des chaînes ou entiers littéraux.</p>
<p>Le module <a><code>collections</code></a> inclus les implémentations de nombreuses structures de données qui étendent celles trouvées dans d&rsquo;autres modules. Par exemple, <code>Deque</code> est une file d&rsquo;attente double, qui permet l&rsquo;addition ou la suppression d&rsquo;éléments à chaque extrémité. <code>defaultdict</code> est un dictionnaire qui répond avec une valeur par défaut si une clé est manquante, alors que <code>OrderedDict</code> se souvient de la séquence dans laquelle les éléments sont ajoutés. <code>namedtuple</code> étend le tuple normal pour donner à chaque item membre un nom d&rsquo;attribut en supplément de l&rsquo;index numérique.</p>
<p>Pour de grandes quantités de données, un <a><code>array</code></a> peut utiliser plus efficacement la mémoire qu&rsquo;une liste. Puisqu&rsquo;un <code>array</code> est limité à un simple type de donnée, il peut utiliser une représentation de mémoire plus compacte qu&rsquo;une <code>list</code> à usage général. En même temps, les instances <code>array</code> peuvent être manipulées en utilisant beaucoup des mêmes méthodes qu&rsquo;une <code>list</code>, ainsi il peut être possible de remplacer une <code>list</code> avec un <code>array</code> sans faire beaucoup de changements.</p>
<p>Le tri d&rsquo;items dans une séquence est un aspect fondamental de la manipulation de données. La <code>list</code> de Python inclus une méthode <code>sort()</code>, mais parfois il est plus efficient de maintenir une liste dans un ordre trié, sans la trier à nouveau, à chaque fois que son contenu a changé.</p>
<p>Les fonctions dans <a><code>heapq</code></a> modifient le contenu d&rsquo;une liste tout en préservant l&rsquo;ordre trié de la liste avec une faible surcharge.</p>
<p>Une autre option pour construire des listes triés ou des tableaux est <a><code>bisect</code></a>. Il utilise une recherche binaire pour trouver le point d&rsquo;insertion des nouveaux items, et est une alternative au tri répété d&rsquo;une liste qui change fréquemment.</p>
<p>Bien que la <code>list</code> native peut simuler une queue, en utilisant les méthodes <code>insert()</code> et <code>pop()</code>, ceci n&rsquo;est pas sûr. Pour avoir de vraies communications ordonnées entre les threads, utilisez le module <a><code>queue</code></a>. <a><code>multiprocessing</code></a> inclus une version de <code>Queue</code> qui fonctionne entre processus, rendant plus facile la conversion d&rsquo;un programme multithread pour utiliser des processus à la place.</p>
<p><a><code>struct</code></a> est utile pour décoder les données d&rsquo;une autre application, qui viennent peut être d&rsquo;un fichier binaire ou d&rsquo;un flux de données, dans les types natifs de Python pour une manipulation plus facile.</p>
<p>Ce chapitre couvre deux modules relatifs à la gestion de la mémoire. Pour des structures de données hautement interconnectées, telles que des graphiques et des arbres, utilisez <a><code>weakref</code></a> pour maintenir des références tout en permettant que le récupérateur de mémoire nettoie les objets après qu&rsquo;ils ne soient plus nécessaires. Utilisez les fonctions dans <a><code>copy</code></a> pour dupliquer des structures de données et leurs contenus, incluant les copies récursives avec <code>deepcopy()</code>.</p>
<p>Déboguer des structures de données peut consommer du temps, spécialement lorsque vous parcourez les sorties imprimées de grandes séquences ou de dictionnaires. Utilisez <a><code>pprint</code></a> pour créer des représentations faciles à lire qui peuvent être imprimées dans la console ou écrites dans un fichier journal pour déboguer facilement.</p>
<p>Enfin, si les types disponibles ne répondent pas aux exigences, sous-classez l&rsquo;un des types natifs et personnalisez-le, ou créez un nouveau type de conteneur en utilisant l&rsquo;une des classes de base abstraites définies dans les <a><code>collections</code></a> en tant que base de départ.</p>
<ul>
<li><a>enum - Type d&rsquo;Énumération</a></li>
<li><a>collections - Types de Données de Conteneur</a></li>
<li><a>array - Séquence de Données de Type Fixé</a></li>
<li><a>heapq - Algorithme de Tri Heap</a></li>
<li><a>bisect - Maintenir les Listes dans un Ordre Trié</a></li>
<li><a>queue - Implémentation FIFO Thread-Safe</a></li>
<li><a>struct - Structures de Données Binaires</a></li>
<li><a>weakref - Références Impermanentes aux Objets</a></li>
<li><a>copy - Objets Dupliqués</a></li>
<li><a>pprint - Structures de Données Pretty-Print</a></li>
</ul>
<h2 id="enum---type-dénumération">enum - Type d&rsquo;Énumération</h2>
<p>Le module <code>enum</code> définit un type d&rsquo;énumération avec des capacités d&rsquo;itération et de comparaison. Il peut être utilisé pour créer des symboles bien définis pour des valeurs, à la place des chaînes ou entiers littéraux.</p>
<h3 id="créer-des-énumérations">Créer des Énumérations</h3>
<p>Une nouvelle énumération est définie par l&rsquo;utilisation de la syntaxe <code>class</code> en sous-classant <code>Enum</code> et en ajoutant des attributs de classe décrivant les valeurs.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_create.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Member name: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(BugStatus<span style="color:#5bc4bf">.</span>wont_fix<span style="color:#5bc4bf">.</span>name))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Member value: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(BugStatus<span style="color:#5bc4bf">.</span>wont_fix<span style="color:#5bc4bf">.</span>value))
</span></span></code></pre></div><p>Les membres de <code>Enum</code> sont convertis en instances à mesure que la classe est analysée. Chaque instance a une propriété <code>name</code> correspondant au nom de membre et une propriété <code>value</code> correspondante à la valeur assignée au nom dans la définition de classe.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_create.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Member name: wont_fix
</span></span><span style="display:flex;"><span>Member value: <span style="color:#f99b15">4</span>
</span></span></code></pre></div><h3 id="itération">Itération</h3>
<p>Itérer sur l&rsquo;énumération <code>class</code> produit des membres individuels d&rsquo;énumération.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_iterate.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> status <span style="color:#5bc4bf">in</span> BugStatus:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:15}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(status<span style="color:#5bc4bf">.</span>name, status<span style="color:#5bc4bf">.</span>value))
</span></span></code></pre></div><p>Les membres sont produits dans l&rsquo;ordre dans lequel ils sont déclarés dans la définition de classe.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_iterate.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">new</span>             <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">incomplete</span>      <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">invalid</span>         <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">wont_fix</span>        <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">in_progress</span>     <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_committed</span>   <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_released</span>    <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span></code></pre></div><h3 id="comparer-les-énumérations">Comparer les Énumérations</h3>
<p>Parce que les membres d&rsquo;énumération ne sont pas ordonnés, ils supportent la comparaison seulement par identité et égalité.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_comparison.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>actual_state <span style="color:#5bc4bf">=</span> BugStatus<span style="color:#5bc4bf">.</span>wont_fix
</span></span><span style="display:flex;"><span>desired_state <span style="color:#5bc4bf">=</span> BugStatus<span style="color:#5bc4bf">.</span>fix_released
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Equality:&#39;</span>,
</span></span><span style="display:flex;"><span>      actual_state <span style="color:#5bc4bf">==</span> desired_state,
</span></span><span style="display:flex;"><span>      actual_state <span style="color:#5bc4bf">==</span> BugStatus<span style="color:#5bc4bf">.</span>wont_fix)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Identity:&#39;</span>,
</span></span><span style="display:flex;"><span>      actual_state <span style="color:#5bc4bf">is</span> desired_state,
</span></span><span style="display:flex;"><span>      actual_state <span style="color:#5bc4bf">is</span> BugStatus<span style="color:#5bc4bf">.</span>wont_fix)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Ordered by value:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>join(<span style="color:#48b685">&#39;  &#39;</span> <span style="color:#5bc4bf">+</span> s<span style="color:#5bc4bf">.</span>name <span style="color:#815ba4">for</span> s <span style="color:#5bc4bf">in</span> sorted(BugStatus)))
</span></span><span style="display:flex;"><span><span style="color:#815ba4">except</span> <span style="color:#ef6155">TypeError</span> <span style="color:#815ba4">as</span> err:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;  Cannot sort: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(err))
</span></span></code></pre></div><p>Les opérateurs de comparaison plus-grand-que et plus-petit-que soulèvent des erreurs d&rsquo;exceptions <code>TypeErrors</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_comparison.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Equality: False True
</span></span><span style="display:flex;"><span>Identity: False True
</span></span><span style="display:flex;"><span>Ordered by value:
</span></span><span style="display:flex;"><span>  Cannot sort: <span style="color:#48b685">&#39;&lt;&#39;</span> not supported between instances of <span style="color:#48b685">&#39;BugStatus
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;</span> and <span style="color:#48b685">&#39;BugStatus&#39;</span>
</span></span></code></pre></div><p>Utilisez la classe <code>IntEnum</code> pour les énumérations dans laquelle les membres doivent se comporter comme des nombres - par exemple, pour supporter les comparaisons.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_intenum.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>IntEnum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Ordered by value:&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>join(<span style="color:#48b685">&#39;  &#39;</span> <span style="color:#5bc4bf">+</span> s<span style="color:#5bc4bf">.</span>name <span style="color:#815ba4">for</span> s <span style="color:#5bc4bf">in</span> sorted(BugStatus)))
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_intenum.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Ordered by value:
</span></span><span style="display:flex;"><span>  fix_released
</span></span><span style="display:flex;"><span>  fix_committed
</span></span><span style="display:flex;"><span>  in_progress
</span></span><span style="display:flex;"><span>  wont_fix
</span></span><span style="display:flex;"><span>  invalid
</span></span><span style="display:flex;"><span>  incomplete
</span></span><span style="display:flex;"><span>  new
</span></span></code></pre></div><h3 id="valeurs-dénumération-uniques">Valeurs d&rsquo;Énumération Uniques</h3>
<p>Les membres d&rsquo;énumération avec les mêmes valeurs sont suivis comme des références d&rsquo;alias du même objet membre. Les alias n&rsquo;entraînent pas la présence de valeurs répétées dans l&rsquo;itérateur pour <code>Enum</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_aliases.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    by_design <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    closed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> status <span style="color:#5bc4bf">in</span> BugStatus:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:15}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(status<span style="color:#5bc4bf">.</span>name, status<span style="color:#5bc4bf">.</span>value))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Same: by_design is wont_fix: &#39;</span>,
</span></span><span style="display:flex;"><span>      BugStatus<span style="color:#5bc4bf">.</span>by_design <span style="color:#5bc4bf">is</span> BugStatus<span style="color:#5bc4bf">.</span>wont_fix)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Same: closed is fix_released: &#39;</span>,
</span></span><span style="display:flex;"><span>      BugStatus<span style="color:#5bc4bf">.</span>closed <span style="color:#5bc4bf">is</span> BugStatus<span style="color:#5bc4bf">.</span>fix_released)
</span></span></code></pre></div><p>Parce que <code>by_design</code> et <code>closed</code> sont des alias pour d&rsquo;autres membres, ils n&rsquo;apparaissent pas séparément dans la sortie lors de l&rsquo;itération de <code>Enum</code>. Le nom canonique pour un membre est le premier nom attaché à la valeur.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_aliases.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">new</span>             <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">incomplete</span>      <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">invalid</span>         <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">wont_fix</span>        <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">in_progress</span>     <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_committed</span>   <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_released</span>    <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Same: by_design is wont_fix:  True
</span></span><span style="display:flex;"><span>Same: closed is fix_released:  True
</span></span></code></pre></div><p>Pour que tous les membres aient des valeurs uniques, ajoutez le décorateur <code>@unique</code> à <code>Enum</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_unique_enforce.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">@enum.unique</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># This will trigger an error with unique applied.</span>
</span></span><span style="display:flex;"><span>    by_design <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>    closed <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span></code></pre></div><p>Les membres qui ont des valeurs répétées déclenchent une erreur d&rsquo;exception <code>ValueError</code> quand la classe <code>Enum</code> est interprétée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_unique_enforce.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Traceback <span style="color:#5bc4bf">(</span>most recent call last<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;enum_unique_enforce.py&#34;</span>, line 11, in &lt;module&gt;
</span></span><span style="display:flex;"><span>    class BugStatus<span style="color:#5bc4bf">(</span>enum.Enum<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;.../lib/python3.7/enum.py&#34;</span>, line 848, in unique
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>enumeration, alias_details<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>ValueError: duplicate values found in &lt;enum <span style="color:#48b685">&#39;BugStatus&#39;</span>&gt;:
</span></span><span style="display:flex;"><span>by_design -&gt; wont_fix, closed -&gt; fix_released
</span></span></code></pre></div><h3 id="création-dénumérations-par-programme">Création d&rsquo;Énumérations par Programme</h3>
<p>Dans certains cas, il est plus pratique de créer des énumérations par programme, plutôt que les coder en dur dans une définition de classe. Pour ces situations, <code>Enum</code> prend aussi en charge le fait de passer les noms des membres et les valeurs au constructeur de classe.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_programmatic_create.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>BugStatus <span style="color:#5bc4bf">=</span> enum<span style="color:#5bc4bf">.</span>Enum(
</span></span><span style="display:flex;"><span>    value<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;BugStatus&#39;</span>,
</span></span><span style="display:flex;"><span>    names<span style="color:#5bc4bf">=</span>(<span style="color:#48b685">&#39;fix_released fix_committed in_progress &#39;</span>
</span></span><span style="display:flex;"><span>           <span style="color:#48b685">&#39;wont_fix invalid incomplete new&#39;</span>),
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Member: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(BugStatus<span style="color:#5bc4bf">.</span>new))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">All members:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> status <span style="color:#5bc4bf">in</span> BugStatus:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:15}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(status<span style="color:#5bc4bf">.</span>name, status<span style="color:#5bc4bf">.</span>value))
</span></span></code></pre></div><p>L&rsquo;argument <code>value</code> est le nom de l&rsquo;énumération, qui est utilisée pour construire la représentation des membres. L&rsquo;argument <code>names</code> liste les membres de l&rsquo;énumération. Quand une chaîne unique est passée, elle est divisée en espaces et en virgules, et les jetons résultants sont utilisés comme noms pour les membres, auxquels sont automatiquement attribuées des valeurs commençant par <code>1</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_programmatic_create.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Member: BugStatus.new
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>All members:
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_released</span>    <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_committed</span>   <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">in_progress</span>     <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">wont_fix</span>        <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">invalid</span>         <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">incomplete</span>      <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">new</span>             <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span></code></pre></div><p>Pour plus de contrôles sur les valeurs associées aux membres, la chaîne <code>names</code> peut être remplacée par une séquence de deux tuples ou un dictionnaire faisant correspondre des noms aux valeurs.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_programmatic_mapping.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>BugStatus <span style="color:#5bc4bf">=</span> enum<span style="color:#5bc4bf">.</span>Enum(
</span></span><span style="display:flex;"><span>    value<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;BugStatus&#39;</span>,
</span></span><span style="display:flex;"><span>    names<span style="color:#5bc4bf">=</span>[
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#f99b15">7</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;incomplete&#39;</span>, <span style="color:#f99b15">6</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;invalid&#39;</span>, <span style="color:#f99b15">5</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;wont_fix&#39;</span>, <span style="color:#f99b15">4</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;in_progress&#39;</span>, <span style="color:#f99b15">3</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;fix_committed&#39;</span>, <span style="color:#f99b15">2</span>),
</span></span><span style="display:flex;"><span>        (<span style="color:#48b685">&#39;fix_released&#39;</span>, <span style="color:#f99b15">1</span>),
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;All members:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> status <span style="color:#5bc4bf">in</span> BugStatus:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:15}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(status<span style="color:#5bc4bf">.</span>name, status<span style="color:#5bc4bf">.</span>value))
</span></span></code></pre></div><p>Dans cet exemple, une liste de deux tuples est donnée au lieu d&rsquo;une chaîne unique contenant seulement les noms des membres. Cela permet de reconstruire l&rsquo;énumération <code>BugStatus</code> avec les membres dans le même ordre que la version définie dans <code>enum_create.py</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_programmatic_mapping.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>All members:
</span></span><span style="display:flex;"><span><span style="color:#ef6155">new</span>             <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">incomplete</span>      <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">invalid</span>         <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">wont_fix</span>        <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">in_progress</span>     <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_committed</span>   <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">fix_released</span>    <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span></code></pre></div><h3 id="valeurs-des-membres-non-entiers">Valeurs des Membres Non Entiers</h3>
<p>Les valeurs des membres d&rsquo;énumération ne sont pas restreints aux entiers. En fait, tout type d&rsquo;objet peut être associé avec un membre. Si la valeur est un tuple, les membres sont passés en tant qu&rsquo;argument individuel à <code>__init__()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_tuple_values.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">7</span>, [<span style="color:#48b685">&#39;incomplete&#39;</span>,
</span></span><span style="display:flex;"><span>               <span style="color:#48b685">&#39;invalid&#39;</span>,
</span></span><span style="display:flex;"><span>               <span style="color:#48b685">&#39;wont_fix&#39;</span>,
</span></span><span style="display:flex;"><span>               <span style="color:#48b685">&#39;in_progress&#39;</span>])
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">6</span>, [<span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;wont_fix&#39;</span>])
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">5</span>, [<span style="color:#48b685">&#39;new&#39;</span>])
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">4</span>, [<span style="color:#48b685">&#39;new&#39;</span>])
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">3</span>, [<span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span>])
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">2</span>, [<span style="color:#48b685">&#39;in_progress&#39;</span>, <span style="color:#48b685">&#39;fix_released&#39;</span>])
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">1</span>, [<span style="color:#48b685">&#39;new&#39;</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, num, transitions):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>num <span style="color:#5bc4bf">=</span> num
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>transitions <span style="color:#5bc4bf">=</span> transitions
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">can_transition</span>(self, new_state):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> new_state<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">in</span> self<span style="color:#5bc4bf">.</span>transitions
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Name:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Value:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>value)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Custom attribute:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>transitions)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Using attribute:&#39;</span>,
</span></span><span style="display:flex;"><span>      BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>can_transition(BugStatus<span style="color:#5bc4bf">.</span>new))
</span></span></code></pre></div><p>Dans cet exemple, chaque valeur de membre est un tuple contenant l&rsquo;ID numérique (qui peut être enregistré dans une base de données) et une liste de transitions valide, sortant de l&rsquo;état actuel.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_tuple_values.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name: BugStatus.in_progress
</span></span><span style="display:flex;"><span>Value: <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span><span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Custom attribute: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Using attribute: True
</span></span></code></pre></div><p>Pour les cas les plus complexes, les tuples peuvent devenir difficiles à manier. Puisque les valeurs des membres peuvent être n&rsquo;importe quel type d&rsquo;objet, les dictionnaires peuvent être utilisés pour les cas où il y a beaucoup d&rsquo;attributs distincts à suivre pour chaque valeur d&rsquo;énumération. Les valeurs complexes sont directement transmises à <code>__init __ ()</code> en tant que seul argument autre que <code>self</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># enum_complex_values.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">enum</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">BugStatus</span>(enum<span style="color:#5bc4bf">.</span>Enum):
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    new <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">7</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;incomplete&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;invalid&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;wont_fix&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;in_progress&#39;</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    incomplete <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">6</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;wont_fix&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    invalid <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">5</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;new&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    wont_fix <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">4</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;new&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    in_progress <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">3</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    fix_committed <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">2</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;in_progress&#39;</span>, <span style="color:#48b685">&#39;fix_released&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    fix_released <span style="color:#5bc4bf">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;num&#39;</span>: <span style="color:#f99b15">1</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;transitions&#39;</span>: [<span style="color:#48b685">&#39;new&#39;</span>],
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, vals):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>num <span style="color:#5bc4bf">=</span> vals[<span style="color:#48b685">&#39;num&#39;</span>]
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>transitions <span style="color:#5bc4bf">=</span> vals[<span style="color:#48b685">&#39;transitions&#39;</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">can_transition</span>(self, new_state):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> new_state<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">in</span> self<span style="color:#5bc4bf">.</span>transitions
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Name:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Value:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>value)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Custom attribute:&#39;</span>, BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>transitions)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Using attribute:&#39;</span>,
</span></span><span style="display:flex;"><span>      BugStatus<span style="color:#5bc4bf">.</span>in_progress<span style="color:#5bc4bf">.</span>can_transition(BugStatus<span style="color:#5bc4bf">.</span>new))
</span></span></code></pre></div><p>Cet exemple exprime les mêmes données que l&rsquo;exemple précédent, utilisant des dictionnaires plutôt que des tuples.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 enum_complex_values.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Name: BugStatus.in_progress
</span></span><span style="display:flex;"><span>Value: <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;num&#39;</span>: 3, <span style="color:#48b685">&#39;transitions&#39;</span>: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span><span style="color:#5bc4bf">]}</span>
</span></span><span style="display:flex;"><span>Custom attribute: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;new&#39;</span>, <span style="color:#48b685">&#39;fix_committed&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Using attribute: True
</span></span></code></pre></div><h3 id="lire-aussi">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/enum.html" rel="external">Documentation standard de la bibliothèque pour enum</a></li>
<li><strong><a title="Adding an Enum type to the Python standard library" href="https://www.python.org/dev/peps/pep-0435" rel="external">PEP 435</a></strong> - Ajouter un type Enum à la bibliothèque standard Python</li>
<li><a title="The original inspiration for enum, by Barry Warsaw." href="http://pythonhosted.org/flufl.enum/" rel="external">flufl.enum</a> – L&rsquo;inspiration originelle d&rsquo;enum, par by Barry Warsaw.</li>
</ul>
<h2 id="collections---types-de-données-de-conteneur">collections - Types de Données de Conteneur</h2>
<p><strong>But</strong> : Types de données de conteneur.</p>
<p>Le module <code>collections</code> inclus les types de données de conteneur au-delà des types natifs <code>list</code>, <code>dict</code> et <code>tuple</code>.</p>
<ul>
<li><a>ChainMap - Recherche dans plusieurs dictionnaires</a></li>
<li><a>Counter - Compter les objets hachables</a></li>
<li><a>defaultdict - Retourner une valeur par défaut aux clés manquantes</a></li>
<li><a>deque - File d&rsquo;attente double</a></li>
<li><a>namedtuple - Sous-classe de tuple avec champs nommés</a></li>
<li><a>OrderedDict - Se souvenir de l&rsquo;ordre des clés ajoutées à un dictionnaire</a></li>
<li><a>collections.abc - Classes de base abstraites pour les conteneurs</a></li>
</ul>
<h3 id="lire-aussi-1">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/collections.html" rel="external">Documentation standard de la bibliothèque pour collections</a></li>
<li><a>Notes de portage de Python 2 à 3 pour les collections</a></li>
<li><strong><a href="https://www.python.org/dev/peps/pep-0342" rel="external">PEP 342</a></strong> - Coroutines via Générateurs Améliorés</li>
<li><strong><a href="https://www.python.org/dev/peps/pep-0492" rel="external">PEP 492</a></strong> - Coroutines avec syntaxe <code>async</code> et <code>await</code></li>
</ul>
<h3 id="chainmap---recherche-dans-plusieurs-dictionnaires">ChainMap - Recherche dans plusieurs dictionnaires</h3>
<p>La classe <code>ChainMap</code> gère une séquence de dictionnaires, et recherche au-travers, dans l&rsquo;ordre où ils sont donnés, pour trouver les valeurs associées aux clés. Une <code>ChainMap</code> constitue un bon conteneur &ldquo;contextuel&rdquo;, car il peut être traité comme une pile pour laquelle des modifications sont apportées à mesure que la pile grandit, ces modifications étant à nouveau ignorées à mesure que la pile se réduit.</p>
<h4 id="accéder-à-des-valeurs">Accéder à des valeurs</h4>
<p>La <code>ChainMap</code> supporte la même API qu&rsquo;une dictionnaire classique pour accéder aux valeurs existantes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_read.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Individual Values&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;a = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;a&#39;</span>]))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;b = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;b&#39;</span>]))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;c = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Keys = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(list(m<span style="color:#5bc4bf">.</span>keys())))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Values = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(list(m<span style="color:#5bc4bf">.</span>values())))
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Items:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> m<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(k, v))
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;&#34;d&#34; in m: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format((<span style="color:#48b685">&#39;d&#39;</span> <span style="color:#5bc4bf">in</span> m)))
</span></span></code></pre></div><p>Les correspondances sous-jacentes font l&rsquo;objet d&rsquo;une recherche dans l&rsquo;ordre dans lequel elles ont été transmises au constructeur, ainsi la valeur indiquée pour la clé <code>c</code> provient du dictionnaire <code>a</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_read.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Individual Values
</span></span><span style="display:flex;"><span><span style="color:#ef6155">a</span> <span style="color:#5bc4bf">=</span> A
</span></span><span style="display:flex;"><span><span style="color:#ef6155">b</span> <span style="color:#5bc4bf">=</span> B
</span></span><span style="display:flex;"><span><span style="color:#ef6155">c</span> <span style="color:#5bc4bf">=</span> C
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">Keys</span> <span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;a&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">Values</span> <span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Items:
</span></span><span style="display:flex;"><span><span style="color:#ef6155">b</span> <span style="color:#5bc4bf">=</span> B
</span></span><span style="display:flex;"><span><span style="color:#ef6155">c</span> <span style="color:#5bc4bf">=</span> C
</span></span><span style="display:flex;"><span><span style="color:#ef6155">a</span> <span style="color:#5bc4bf">=</span> A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;d&#34;</span> in m: False
</span></span></code></pre></div><h4 id="réordonner">Réordonner</h4>
<p>La <code>ChainMap</code> enregistre dans son attribut <code>maps</code> une liste de correspondances, sur laquelle elle fait sa recherche. Cette liste est mutable, ainsi il est possible d&rsquo;ajouter de nouvelles correspondances directement ou de changer l&rsquo;ordre des éléments pour contrôler la recherche et le comportement de mise à jour.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_reorder.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(m<span style="color:#5bc4bf">.</span>maps)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;c = </span><span style="color:#f99b15">{}</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># reverse the list</span>
</span></span><span style="display:flex;"><span>m<span style="color:#5bc4bf">.</span>maps <span style="color:#5bc4bf">=</span> list(reversed(m<span style="color:#5bc4bf">.</span>maps))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(m<span style="color:#5bc4bf">.</span>maps)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;c = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span></code></pre></div><p>Quand la liste de correspondances est renversée, la valeur associée à <code>c</code> change.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_reorder.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">}]</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">c</span> <span style="color:#5bc4bf">=</span> C
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}]</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">c</span> <span style="color:#5bc4bf">=</span> D
</span></span></code></pre></div><h4 id="mise-à-jour-des-valeurs">Mise à jour des Valeurs</h4>
<p>Une <code>ChainMap</code> ne met pas en cache les valeurs dans les correspondances sous-jacentes. Ainsi, si leur contenu est modifié, les résultats sont reflétés lors de l&rsquo;accès à <code>ChainMap</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_update_behind.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Before: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span><span style="display:flex;"><span>a[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;E&#39;</span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;After : </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span></code></pre></div><p>Changer les valeurs associées avec les clés existantes et ajouter de nouveaux éléments fonctionne de la même manière.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_update_behind.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Before: C
</span></span><span style="display:flex;"><span>After : E
</span></span></code></pre></div><p>Il est également possible de définir directement des valeurs via <code>ChainMap</code>, bien que seule la première correspondance de la chaîne soit réellement modifiée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_update_directly.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Before:&#39;</span>, m)
</span></span><span style="display:flex;"><span>m[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;E&#39;</span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;After :&#39;</span>, m)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;a:&#39;</span>, a)
</span></span></code></pre></div><p>Quand la nouvelle valeur est enregistrée en utilisant <code>m</code>, la correspondance <code>a</code> est mise à jour.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_update_directly.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Before: ChainMap<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>After : ChainMap<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>a: <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><p><code>ChainMap</code> fournit une méthode pratique pour créer une nouvelle instance avec une correspondance supplémentaire au début de la liste des correspondances pour éviter de modifier les structures de données sous-jacentes existantes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_new_child.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>m2 <span style="color:#5bc4bf">=</span> m1<span style="color:#5bc4bf">.</span>new_child()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m1 before:&#39;</span>, m1)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m2 before:&#39;</span>, m2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m2[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;E&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m1 after:&#39;</span>, m1)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m2 after:&#39;</span>, m2)
</span></span></code></pre></div><p>Ce comportement d&rsquo;empilement est pratique pour utiliser les instances de <code>ChainMap</code> comme contextes de modèles ou d&rsquo;applications. Il est spécifiquement facile d&rsquo;ajouter ou de mettre à jour des valeurs en une itération, puis d&rsquo;annuler les changements pour la prochaine itération.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_new_child.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m1 before: ChainMap<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>m2 before: ChainMap<span style="color:#5bc4bf">({}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>:
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>m1 after: ChainMap<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>m2 after: ChainMap<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span><span style="color:#5bc4bf">}</span>, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>
</span></span></code></pre></div><p>Pour les situations où le nouveau contexte est connu ou natif à l&rsquo;avance, il est aussi possible de passer une correspondance à <code>new_child()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_chainmap_new_child_explicit.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>}
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}
</span></span><span style="display:flex;"><span>c <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(a, b)
</span></span><span style="display:flex;"><span>m2 <span style="color:#5bc4bf">=</span> m1<span style="color:#5bc4bf">.</span>new_child(c)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m1[&#34;c&#34;] = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m1[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;m2[&#34;c&#34;] = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(m2[<span style="color:#48b685">&#39;c&#39;</span>]))
</span></span></code></pre></div><p>Ce qui est l&rsquo;équivalent de :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>m2 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>ChainMap(c, <span style="color:#5bc4bf">*</span>m1<span style="color:#5bc4bf">.</span>maps)
</span></span></code></pre></div><p>et produit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_chainmap_new_child_explicit.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>m1<span style="color:#5bc4bf">[</span><span style="color:#48b685">&#34;c&#34;</span><span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> C
</span></span><span style="display:flex;"><span>m2<span style="color:#5bc4bf">[</span><span style="color:#48b685">&#34;c&#34;</span><span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> E
</span></span></code></pre></div><h3 id="compter-les-objets-hachables">Compter les objets hachables</h3>
<p>Un <code>Counter</code> est un conteneur qui garde une trace du nombre de fois où des valeurs équivalentes sont ajoutées. Il peut être utilisé pour implémenter les mêmes algorithmes pour lesquels d&rsquo;autres langages utilisent couramment des structures de données en sacs ou en multi-ensembles.</p>
<h4 id="initialisation">Initialisation</h4>
<p><code>Counter</code> prend en charge trois formes d&rsquo;initialisation. Son constructeur peut être appelé avec une séquence d&rsquo;items, un dictionnaire contenant des clés et des compteurs, ou en utilisant des arguments de mots-clés qui associent les noms de chaîne aux compteurs.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_init.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(collections<span style="color:#5bc4bf">.</span>Counter([<span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>]))
</span></span><span style="display:flex;"><span>print(collections<span style="color:#5bc4bf">.</span>Counter({<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#f99b15">2</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#f99b15">3</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#f99b15">1</span>}))
</span></span><span style="display:flex;"><span>print(collections<span style="color:#5bc4bf">.</span>Counter(a<span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span>, b<span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span>, c<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>))
</span></span></code></pre></div><p>Les résultats des trois formes d&rsquo;initialisation sont les mêmes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_init.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 3, <span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 3, <span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 3, <span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span></code></pre></div><p>Un <code>Counter</code> vide peut être construit sans arguments et rempli via la méthode <code>update()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_update.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter()
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Initial :&#39;</span>, c)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c<span style="color:#5bc4bf">.</span>update(<span style="color:#48b685">&#39;abcdaab&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Sequence:&#39;</span>, c)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c<span style="color:#5bc4bf">.</span>update({<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#f99b15">1</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#f99b15">5</span>})
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Dict    :&#39;</span>, c)
</span></span></code></pre></div><p>Les valeurs comptées sont augmentées en se basant sur les nouvelles données, plutôt que remplacées. Dans l&rsquo;exemple précédent, le compteur pour <code>a</code> va de <code>3</code> à <code>4</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_update.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Initial : Counter<span style="color:#5bc4bf">()</span>
</span></span><span style="display:flex;"><span>Sequence: Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: 3, <span style="color:#48b685">&#39;b&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1, <span style="color:#48b685">&#39;d&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>Dict    : Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;d&#39;</span>: 6, <span style="color:#48b685">&#39;a&#39;</span>: 4, <span style="color:#48b685">&#39;b&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span></code></pre></div><h4 id="accéder-aux-compteurs">Accéder aux Compteurs</h4>
<p>Une fois qu&rsquo;un <code>Counter</code> est rempli, ses valeurs peuvent être récupérées en utilisant l&rsquo;API de dictionnaire.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_get_values.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter(<span style="color:#48b685">&#39;abcdaab&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> letter <span style="color:#5bc4bf">in</span> <span style="color:#48b685">&#39;abcde&#39;</span>:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685"> : </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(letter, c[letter]))
</span></span></code></pre></div><p>Le <code>Counter</code> ne soulève pas d&rsquo;erreur <code>KeyError</code> pour les items inconnus. Si une valeur n&rsquo;est pas vue dans l&rsquo;entrée (comme c&rsquo;est le cas dans l&rsquo;exemple avec <code>e</code>), son compteur est à <code>0</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_get_values.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a : <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>b : <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>c : <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>d : <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>e : <span style="color:#f99b15">0</span>
</span></span></code></pre></div><p>La méthode <code>elements()</code> retourne un itérateur qui produit tous les items connus de <code>Counter</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_elements.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter(<span style="color:#48b685">&#39;extremely&#39;</span>)
</span></span><span style="display:flex;"><span>c[<span style="color:#48b685">&#39;z&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>print(c)
</span></span><span style="display:flex;"><span>print(list(c<span style="color:#5bc4bf">.</span>elements()))
</span></span></code></pre></div><p>L&rsquo;ordre des éléments n&rsquo;est pas garanti, et les items avec des compteurs inférieurs ou égales à zéro ne sont pas inclus.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_elements.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;e&#39;</span>: 3, <span style="color:#48b685">&#39;x&#39;</span>: 1, <span style="color:#48b685">&#39;t&#39;</span>: 1, <span style="color:#48b685">&#39;r&#39;</span>: 1, <span style="color:#48b685">&#39;m&#39;</span>: 1, <span style="color:#48b685">&#39;l&#39;</span>: 1, <span style="color:#48b685">&#39;y&#39;</span>: 1,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;z&#39;</span>: 0<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;t&#39;</span>, <span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;l&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span><span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><p>Utilisez <code>most_common()</code>pour produire une séquence de <code>n</code> valeurs d&rsquo;entrées les plus fréquemment rencontrées et de leurs compteurs respectifs.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_most_common.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter()
</span></span><span style="display:flex;"><span><span style="color:#815ba4">with</span> open(<span style="color:#48b685">&#39;/usr/share/dict/words&#39;</span>, <span style="color:#48b685">&#39;rt&#39;</span>) <span style="color:#815ba4">as</span> f:
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> line <span style="color:#5bc4bf">in</span> f:
</span></span><span style="display:flex;"><span>        c<span style="color:#5bc4bf">.</span>update(line<span style="color:#5bc4bf">.</span>rstrip()<span style="color:#5bc4bf">.</span>lower())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Most common:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> letter, count <span style="color:#5bc4bf">in</span> c<span style="color:#5bc4bf">.</span>most_common(<span style="color:#f99b15">3</span>):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685">: </span><span style="color:#f99b15">{:&gt;7}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(letter, count))
</span></span></code></pre></div><p>Cet exemple compte les lettres apparaissant dans tous les mots du dictionnaire système pour produire une distribution de fréquence, puis imprime les trois lettres les plus courantes. Si vous omettez l&rsquo;argument à <code>most_common ()</code>, vous obtenez une liste de tous les éléments, par ordre de fréquence.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_most_common.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Most common:
</span></span><span style="display:flex;"><span>e:  <span style="color:#f99b15">235331</span>
</span></span><span style="display:flex;"><span>i:  <span style="color:#f99b15">201032</span>
</span></span><span style="display:flex;"><span>a:  <span style="color:#f99b15">199554</span>
</span></span></code></pre></div><h4 id="arithmétique">Arithmétique</h4>
<p>Les instances de <code>Counter</code> supportent l&rsquo;arithmétique et paramètrent des opérations pour l’agrégation des résultats. Cet exemple montre les opérateurs standards pour créer de nouvelles instances de <code>Counter</code>, mais les opérateurs sur place <code>+=</code>, <code>-=</code>, <code>&amp;=</code>, et <code>|=</code> sont aussi supportés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_counter_arithmetic.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>c1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter([<span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>])
</span></span><span style="display:flex;"><span>c2 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>Counter(<span style="color:#48b685">&#39;alphabet&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;C1:&#39;</span>, c1)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;C2:&#39;</span>, c2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Combined counts:&#39;</span>)
</span></span><span style="display:flex;"><span>print(c1 <span style="color:#5bc4bf">+</span> c2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Subtraction:&#39;</span>)
</span></span><span style="display:flex;"><span>print(c1 <span style="color:#5bc4bf">-</span> c2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Intersection (taking positive minimums):&#39;</span>)
</span></span><span style="display:flex;"><span>print(c1 <span style="color:#5bc4bf">&amp;</span> c2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Union (taking maximums):&#39;</span>)
</span></span><span style="display:flex;"><span>print(c1 <span style="color:#5bc4bf">|</span> c2)
</span></span></code></pre></div><p>Chaque fois qu&rsquo;un nouveau <code>Counter</code> est produit par opération, chaque item avec un compteur zéro ou négatif est supprimé. Le compteur pour <code>a</code> est le même dans <code>c1</code> et <code>c2</code>, la soustraction le laisse à zéro.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_counter_arithmetic.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>C1: Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 3, <span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>C2: Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;l&#39;</span>: 1, <span style="color:#48b685">&#39;p&#39;</span>: 1, <span style="color:#48b685">&#39;h&#39;</span>: 1, <span style="color:#48b685">&#39;b&#39;</span>: 1, <span style="color:#48b685">&#39;e&#39;</span>: 1, <span style="color:#48b685">&#39;t&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Combined counts:
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: 4, <span style="color:#48b685">&#39;b&#39;</span>: 4, <span style="color:#48b685">&#39;c&#39;</span>: 1, <span style="color:#48b685">&#39;l&#39;</span>: 1, <span style="color:#48b685">&#39;p&#39;</span>: 1, <span style="color:#48b685">&#39;h&#39;</span>: 1, <span style="color:#48b685">&#39;e&#39;</span>: 1, <span style="color:#48b685">&#39;t&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Subtraction:
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Intersection <span style="color:#5bc4bf">(</span>taking positive minimums<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;b&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Union <span style="color:#5bc4bf">(</span>taking maximums<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>Counter<span style="color:#5bc4bf">({</span><span style="color:#48b685">&#39;b&#39;</span>: 3, <span style="color:#48b685">&#39;a&#39;</span>: 2, <span style="color:#48b685">&#39;c&#39;</span>: 1, <span style="color:#48b685">&#39;l&#39;</span>: 1, <span style="color:#48b685">&#39;p&#39;</span>: 1, <span style="color:#48b685">&#39;h&#39;</span>: 1, <span style="color:#48b685">&#39;e&#39;</span>: 1, <span style="color:#48b685">&#39;t&#39;</span>: 1<span style="color:#5bc4bf">})</span>
</span></span></code></pre></div><h3 id="defaultdict---retourner-une-valeur-par-défaut-aux-clés-manquantes">defaultdict - Retourner une Valeur par Défaut aux Clés Manquantes</h3>
<p>Le dictionnaire standard inclut la méthode <code>setdefault()</code> pour récupérer une valeur et en établir une par défaut si la valeur n&rsquo;existe pas. Par contraste, <code>defaultdict</code> permet à l&rsquo;appelant de spécifier la valeur par défaut dès l&rsquo;initialisation du conteneur.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_defaultdict.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">default_factory</span>():
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#48b685">&#39;default value&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>defaultdict(default_factory, foo<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;bar&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;d:&#39;</span>, d)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;foo =&gt;&#39;</span>, d[<span style="color:#48b685">&#39;foo&#39;</span>])
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;bar =&gt;&#39;</span>, d[<span style="color:#48b685">&#39;bar&#39;</span>])
</span></span></code></pre></div><p>Cette méthode fonctionne aussi dans la mesure où il est approprié que toutes les clés aient la même valeur par défaut. Elle peut être spécialement utile si la valeur par défaut est un type utilisé pour l’agrégation ou l&rsquo;accumulation de valeurs, tels que <code>list</code>, <code>set</code>, ou même <code>int</code>. La documentation standard de la bibliothèque inclus de nombreux exemples dans lesquels <code>defaultdict</code> est utilisé de cette manière.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_defaultdict.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d: defaultdict<span style="color:#5bc4bf">(</span>&lt;<span style="color:#815ba4">function</span> default_factory at 0x101341950&gt;,
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;foo&#39;</span>: <span style="color:#48b685">&#39;bar&#39;</span><span style="color:#5bc4bf">})</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">foo</span> <span style="color:#5bc4bf">=</span>&gt; bar
</span></span><span style="display:flex;"><span><span style="color:#ef6155">bar</span> <span style="color:#5bc4bf">=</span>&gt; default value
</span></span></code></pre></div><h3 id="lire-aussi-2">Lire aussi</h3>
<ul>
<li><a title="Exemples utilisant defaultdict" href="https://docs.python.org/fr/3.7/library/collections.html#defaultdict-examples" rel="external">defaultdict : exemples</a> – Exemples d&rsquo;utilisation de <code>defaultdict</code> dans la documentation standard de la bibliothèque</li>
<li><a title="Evolution of Default Dictionaries in Python" href="http://jtauber.com/blog/2008/02/27/evolution_of_default_dictionaries_in_python/" rel="external">Évolution des Dictionnaires par défaut en Python</a> – Article, en anglais, de James Tauber de la relation entre <code>defaultdict</code> et d’autres moyens d’initialisation des dictionnaires.</li>
</ul>
<h3 id="deque---file-dattente-double">deque - File d&rsquo;Attente Double</h3>
<p>Une file d&rsquo;attente double, ou <code>deque</code> prend en charge l&rsquo;ajout ou la suppression d&rsquo;éléments depuis chaque extrémité de la queue. Les piles et les files d’attente les plus couramment utilisées sont des formes dégénérées de deques où les entrées et les sorties sont restreintes à une seule extrémité.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(<span style="color:#48b685">&#39;abcdefg&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Deque:&#39;</span>, d)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Length:&#39;</span>, len(d))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Left end:&#39;</span>, d[<span style="color:#f99b15">0</span>])
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Right end:&#39;</span>, d[<span style="color:#5bc4bf">-</span><span style="color:#f99b15">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d<span style="color:#5bc4bf">.</span>remove(<span style="color:#48b685">&#39;c&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;remove(c):&#39;</span>, d)
</span></span></code></pre></div><p>Puisque les deques sont un type de conteneur de séquences, ils prennent en charge certaines des opérations similaires à <code>list</code>, tel que l&rsquo;examen des contenus avec <code>__getitem__()</code>, déterminer la longueur, et la suppression des éléments depuis le milieu de la queue par correspondance d&rsquo;identité.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_deque.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Deque: deque<span style="color:#5bc4bf">([</span><span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span><span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Length: <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>Left end: a
</span></span><span style="display:flex;"><span>Right end: g
</span></span><span style="display:flex;"><span>remove<span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span>: deque<span style="color:#5bc4bf">([</span><span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span><span style="color:#5bc4bf">])</span>
</span></span></code></pre></div><h4 id="remplissage">Remplissage</h4>
<p>Une deque peut être remplis depuis chaque extrémité, décrite à «gauche» ou à «droite» dans l&rsquo;implémentation Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque_populating.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Add to the right</span>
</span></span><span style="display:flex;"><span>d1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque()
</span></span><span style="display:flex;"><span>d1<span style="color:#5bc4bf">.</span>extend(<span style="color:#48b685">&#39;abcdefg&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;extend    :&#39;</span>, d1)
</span></span><span style="display:flex;"><span>d1<span style="color:#5bc4bf">.</span>append(<span style="color:#48b685">&#39;h&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;append    :&#39;</span>, d1)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Add to the left</span>
</span></span><span style="display:flex;"><span>d2 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque()
</span></span><span style="display:flex;"><span>d2<span style="color:#5bc4bf">.</span>extendleft(range(<span style="color:#f99b15">6</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;extendleft:&#39;</span>, d2)
</span></span><span style="display:flex;"><span>d2<span style="color:#5bc4bf">.</span>appendleft(<span style="color:#f99b15">6</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;appendleft:&#39;</span>, d2)
</span></span></code></pre></div><p>La fonction <code>extendleft()</code> effectue une itération sur son entrée et effectue l&rsquo;équivalent d&rsquo;un <code>appendleft()</code> pour chaque item. Le résultat final est que <code>deque</code> contient la séquence d&rsquo;entrée dans l&rsquo;ordre inverse.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_deque_populating.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>extend    : deque<span style="color:#5bc4bf">([</span><span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span><span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>append    : deque<span style="color:#5bc4bf">([</span><span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>, <span style="color:#48b685">&#39;e&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span>, <span style="color:#48b685">&#39;h&#39;</span><span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>extendleft: deque<span style="color:#5bc4bf">([</span>5, 4, 3, 2, 1, 0<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>appendleft: deque<span style="color:#5bc4bf">([</span>6, 5, 4, 3, 2, 1, 0<span style="color:#5bc4bf">])</span>
</span></span></code></pre></div><h4 id="consommation">Consommation</h4>
<p>De la même manière, les éléments de <code>deque</code> peuvent être consommés depuis les deux extrémités, ou de l&rsquo;une, selon l&rsquo;algorithme qui est appliqué.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque_consuming.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;From the right:&#39;</span>)
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(<span style="color:#48b685">&#39;abcdefg&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>        print(d<span style="color:#5bc4bf">.</span>pop(), end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">except</span> <span style="color:#ef6155">IndexError</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">break</span>
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">From the left:&#39;</span>)
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(range(<span style="color:#f99b15">6</span>))
</span></span><span style="display:flex;"><span><span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>        print(d<span style="color:#5bc4bf">.</span>popleft(), end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">except</span> <span style="color:#ef6155">IndexError</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">break</span>
</span></span><span style="display:flex;"><span>print()
</span></span></code></pre></div><p>Utilisez <code>pop()</code> pour supprimer un item depuis l&rsquo;extrémité «droite» de <code>deque</code> et <code>popleft()</code> pour prendre un item depuis l&rsquo;extrémité «gauche».</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_deque_consuming.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>From the right:
</span></span><span style="display:flex;"><span>gfedcba
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>From the left:
</span></span><span style="display:flex;"><span><span style="color:#f99b15">012345</span>
</span></span></code></pre></div><p>Puisque les deques sont des processus sûrs <em>(dits «thead-safe»)</em>, les contenus peuvent être consommés depuis chaque extrémité en même temps, depuis des processus séparés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque_both_ends.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">threading</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">time</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>candle <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(range(<span style="color:#f99b15">5</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">burn</span>(direction, nextSource):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>            next <span style="color:#5bc4bf">=</span> nextSource()
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">except</span> <span style="color:#ef6155">IndexError</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">break</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>            print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:&gt;8}</span><span style="color:#48b685">: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(direction, next))
</span></span><span style="display:flex;"><span>            time<span style="color:#5bc4bf">.</span>sleep(<span style="color:#f99b15">0.1</span>)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:&gt;8}</span><span style="color:#48b685"> done&#39;</span><span style="color:#5bc4bf">.</span>format(direction))
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>left <span style="color:#5bc4bf">=</span> threading<span style="color:#5bc4bf">.</span>Thread(target<span style="color:#5bc4bf">=</span>burn,
</span></span><span style="display:flex;"><span>                        args<span style="color:#5bc4bf">=</span>(<span style="color:#48b685">&#39;Left&#39;</span>, candle<span style="color:#5bc4bf">.</span>popleft))
</span></span><span style="display:flex;"><span>right <span style="color:#5bc4bf">=</span> threading<span style="color:#5bc4bf">.</span>Thread(target<span style="color:#5bc4bf">=</span>burn,
</span></span><span style="display:flex;"><span>                         args<span style="color:#5bc4bf">=</span>(<span style="color:#48b685">&#39;Right&#39;</span>, candle<span style="color:#5bc4bf">.</span>pop))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>left<span style="color:#5bc4bf">.</span>start()
</span></span><span style="display:flex;"><span>right<span style="color:#5bc4bf">.</span>start()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>left<span style="color:#5bc4bf">.</span>join()
</span></span><span style="display:flex;"><span>right<span style="color:#5bc4bf">.</span>join()
</span></span></code></pre></div><p>Les processus dans cet exemple alternent entre chaque extrémité, supprimant les éléments jusqu&rsquo;à ce que <code>deque</code> soit vide.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span> $ python3 collections_deque_both_ends.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> Left: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>Right: <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>Right: <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span> Left: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Right: <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span> Left <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>Right <span style="color:#815ba4">done</span>
</span></span></code></pre></div><h4 id="rotation">Rotation</h4>
<p>Un autre aspect utile de <code>deque</code> est la capacité à se retourner dans chaque direction, et ainsi à sauter par dessus certains items.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque_rotate.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(range(<span style="color:#f99b15">10</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Normal        :&#39;</span>, d)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(range(<span style="color:#f99b15">10</span>))
</span></span><span style="display:flex;"><span>d<span style="color:#5bc4bf">.</span>rotate(<span style="color:#f99b15">2</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Right rotation:&#39;</span>, d)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(range(<span style="color:#f99b15">10</span>))
</span></span><span style="display:flex;"><span>d<span style="color:#5bc4bf">.</span>rotate(<span style="color:#5bc4bf">-</span><span style="color:#f99b15">2</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Left rotation :&#39;</span>, d)
</span></span></code></pre></div><p>La rotation de <code>deque</code> par la droite (utilisant la rotation positive) prend les éléments depuis l&rsquo;extrémité droite et les déplacer à l&rsquo;extrémité gauche. Les retourner par la gauche (avec une valeur négative) prend les items depuis l&rsquo;extrémité gauche et les déplacent vers l&rsquo;extrémité droite. Il peut être utile de visualiser les éléments dans la deque comme étant gravés le long du bord d’un cadran.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_deque_rotate.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Normal        : deque<span style="color:#5bc4bf">([</span>0, 1, 2, 3, 4, 5, 6, 7, 8, 9<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Right rotation: deque<span style="color:#5bc4bf">([</span>8, 9, 0, 1, 2, 3, 4, 5, 6, 7<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Left rotation : deque<span style="color:#5bc4bf">([</span>2, 3, 4, 5, 6, 7, 8, 9, 0, 1<span style="color:#5bc4bf">])</span>
</span></span></code></pre></div><h4 id="contraindre-la-taille-de-la-queue">Contraindre la Taille de la Queue</h4>
<p>Une instance <code>deque</code> peut être configuré avec une longueur maximale, ainsi elle ne pourra jamais grandir plus que sa taille. Quand la file d&rsquo;attente atteint la taille spécifiée, les éléments existants sont abandonnés au profit des nouveaux items ajoutés. Ce comportement est pratique pour chercher les <code>n</code> derniers éléments d&rsquo;un flux d&rsquo;une longueur indéterminé.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_deque_maxlen.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">random</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Set the random seed so we see the same output each time</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># the script is run.</span>
</span></span><span style="display:flex;"><span>random<span style="color:#5bc4bf">.</span>seed(<span style="color:#f99b15">1</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(maxlen<span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span>d2 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>deque(maxlen<span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(<span style="color:#f99b15">5</span>):
</span></span><span style="display:flex;"><span>    n <span style="color:#5bc4bf">=</span> random<span style="color:#5bc4bf">.</span>randint(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">100</span>)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;n =&#39;</span>, n)
</span></span><span style="display:flex;"><span>    d1<span style="color:#5bc4bf">.</span>append(n)
</span></span><span style="display:flex;"><span>    d2<span style="color:#5bc4bf">.</span>appendleft(n)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;D1:&#39;</span>, d1)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;D2:&#39;</span>, d2)
</span></span></code></pre></div><p>La longueur de la file d&rsquo;attente est maintenue quelque soit l&rsquo;extrémité à laquelle sont ajoutés les éléments.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_deque_maxlen.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">n</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">17</span>
</span></span><span style="display:flex;"><span>D1: deque<span style="color:#5bc4bf">([</span>17<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>D2: deque<span style="color:#5bc4bf">([</span>17<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">n</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">72</span>
</span></span><span style="display:flex;"><span>D1: deque<span style="color:#5bc4bf">([</span>17, 72<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>D2: deque<span style="color:#5bc4bf">([</span>72, 17<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">n</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">97</span>
</span></span><span style="display:flex;"><span>D1: deque<span style="color:#5bc4bf">([</span>17, 72, 97<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>D2: deque<span style="color:#5bc4bf">([</span>97, 72, 17<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">n</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">8</span>
</span></span><span style="display:flex;"><span>D1: deque<span style="color:#5bc4bf">([</span>72, 97, 8<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>D2: deque<span style="color:#5bc4bf">([</span>8, 97, 72<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">n</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">32</span>
</span></span><span style="display:flex;"><span>D1: deque<span style="color:#5bc4bf">([</span>97, 8, 32<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>D2: deque<span style="color:#5bc4bf">([</span>32, 8, 97<span style="color:#5bc4bf">]</span>, <span style="color:#ef6155">maxlen</span><span style="color:#5bc4bf">=</span>3<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="lire-aussi-3">Lire aussi</h3>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Double-ended_queue" rel="external">Wikipedia : Deque</a> - Une discussion sur la structure de données deque <em>(en anglais)</em></li>
<li><a href="https://docs.python.org/fr/3.7/library/collections.html#deque-recipes" rel="external">Recettes Deque</a> - Exemples d&rsquo;utilisations des files d&rsquo;attente depuis la documentation de la bibliothèque standard.</li>
</ul>
<h3 id="namedtuple---sous-classe-de-tuple-avec-champs-nommés">namedtuple - Sous-classe de tuple avec champs nommés</h3>
<p>Le <code>tuple</code> standard utilise les index numériques pour accéder à ses membres.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_tuple.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>bob <span style="color:#5bc4bf">=</span> (<span style="color:#48b685">&#39;Bob&#39;</span>, <span style="color:#f99b15">30</span>, <span style="color:#48b685">&#39;male&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Representation:&#39;</span>, bob)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>jane <span style="color:#5bc4bf">=</span> (<span style="color:#48b685">&#39;Jane&#39;</span>, <span style="color:#f99b15">29</span>, <span style="color:#48b685">&#39;female&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Field by index:&#39;</span>, jane[<span style="color:#f99b15">0</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Fields by index:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> p <span style="color:#5bc4bf">in</span> [bob, jane]:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685"> is a </span><span style="color:#f99b15">{}</span><span style="color:#48b685"> year old </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(<span style="color:#5bc4bf">*</span>p))
</span></span></code></pre></div><p>Ce qui fait des tuples des conteneurs pratiques pour des utilisations simples.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_tuple.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Representation: <span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;Bob&#39;</span>, 30, <span style="color:#48b685">&#39;male&#39;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Field by index: Jane
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Fields by index:
</span></span><span style="display:flex;"><span>Bob is a <span style="color:#f99b15">30</span> year old male
</span></span><span style="display:flex;"><span>Jane is a <span style="color:#f99b15">29</span> year old female
</span></span></code></pre></div><p>Par contraste, se souvenir quel index utiliser pour chaque valeur peut entraîner des erreurs, spécialement si le tuple a beaucoup de champs et est construit loin de l&rsquo;endroit où il est utilisé. Un <code>namedtuple</code> assigne des noms, aussi bien que des index numériques, pour chaque membre.</p>
<h4 id="définitions">Définitions</h4>
<p>Les instances <code>namedtuple</code> sont juste plus efficient en mémoire que les tuples ordinaires car ils n&rsquo;ont pas de dictionnaires par instance. Chaque type de <code>namedtuple</code> est représenté par sa propre classe, qui est créée en utilisant la fonction de fabrication <code>namedtuple()</code>. Les arguments sont des noms de la nouvelle classe et une chaîne contenant les noms des éléments.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_person.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Person <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>bob <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">30</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Representation:&#39;</span>, bob)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>jane <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Jane&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">29</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Field by name:&#39;</span>, jane<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Fields by index:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> p <span style="color:#5bc4bf">in</span> [bob, jane]:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685"> is </span><span style="color:#f99b15">{}</span><span style="color:#48b685"> years old&#39;</span><span style="color:#5bc4bf">.</span>format(<span style="color:#5bc4bf">*</span>p))
</span></span></code></pre></div><p>Comme l&rsquo;exemple l&rsquo;illustre, il est possible d&rsquo;accéder aux champs du <code>namedtuple</code> par nom en utilisant la notation (<code>obj.attr</code>) aussi bien que par l&rsquo;utilisation des index positionnés des tuples standards.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_person.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Representation: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>30<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Field by name: Jane
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Fields by index:
</span></span><span style="display:flex;"><span>Bob is <span style="color:#f99b15">30</span> years old
</span></span><span style="display:flex;"><span>Jane is <span style="color:#f99b15">29</span> years old
</span></span></code></pre></div><p>Tout comme un <code>tuple</code> ordinaire, un <code>namedtuple</code> est immuable. Cette restriction permet aux instances <code>tuples</code> d&rsquo;avoir une valeur de hachage cohérente, ce qui rend possible leur utilisation comme clés de dictionnaires et d&rsquo;être incluses dans des ensembles.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_immutable.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Person <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pat <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Pat&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">12</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Representation:&#39;</span>, pat)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pat<span style="color:#5bc4bf">.</span>age <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">21</span>
</span></span></code></pre></div><p>Essayer de changer sa valeur par son nom d&rsquo;attribut résulte en une erreur <code>AttributError</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_immutable.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Representation: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Pat&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>12<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Traceback <span style="color:#5bc4bf">(</span>most recent call last<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;collections_namedtuple_immutable.py&#34;</span>, line 17, in
</span></span><span style="display:flex;"><span>&lt;module&gt;
</span></span><span style="display:flex;"><span>    pat.age <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">21</span>
</span></span><span style="display:flex;"><span>AttributeError: can<span style="color:#ef6155">&#39;</span>t set attribute
</span></span></code></pre></div><h4 id="noms-de-champs-invalides">Noms de Champs Invalides</h4>
<p>Les noms de champs sont invalides s&rsquo;ils sont répétés ou en conflit avec des mots clés Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_bad_fields.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>    collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name class age&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">except</span> <span style="color:#ef6155">ValueError</span> <span style="color:#815ba4">as</span> err:
</span></span><span style="display:flex;"><span>    print(err)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>    collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age age&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">except</span> <span style="color:#ef6155">ValueError</span> <span style="color:#815ba4">as</span> err:
</span></span><span style="display:flex;"><span>    print(err)
</span></span></code></pre></div><p>Comme les noms des champs sont analysés, les valeurs invalides causent des erreurs d&rsquo;exceptions <code>ValueError</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_bad_fields.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Type names and field names cannot be a keyword: <span style="color:#48b685">&#39;class&#39;</span>
</span></span><span style="display:flex;"><span>Encountered duplicate field name: <span style="color:#48b685">&#39;age&#39;</span>
</span></span></code></pre></div><p>Dans les situations où un <code>namedtuple</code> est créé sur la base des valeurs en-dehors du contrôle du programme (telle que représenter les lignes renvoyées par une requête de base de données, lorsque le schéma n&rsquo;est pas connu à l&rsquo;avance), l&rsquo;option <code>rename</code> doit être paramétrée à <code>True</code> pour que les champs invalides soient renommés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_rename.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>with_class <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name class age&#39;</span>,
</span></span><span style="display:flex;"><span>    rename<span style="color:#5bc4bf">=</span><span style="color:#815ba4">True</span>)
</span></span><span style="display:flex;"><span>print(with_class<span style="color:#5bc4bf">.</span>_fields)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>two_ages <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age age&#39;</span>,
</span></span><span style="display:flex;"><span>    rename<span style="color:#5bc4bf">=</span><span style="color:#815ba4">True</span>)
</span></span><span style="display:flex;"><span>print(two_ages<span style="color:#5bc4bf">.</span>_fields)
</span></span></code></pre></div><p>Les nouveaux noms des champs renommés dépendent de leur index dans le tuple, ainsi le champ avec le nom <code>class</code> devient <code>_1</code> et le champ dupliqué <code>age</code> est changé en <code>_2</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_rename.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;name&#39;</span>, <span style="color:#48b685">&#39;_1&#39;</span>, <span style="color:#48b685">&#39;age&#39;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;name&#39;</span>, <span style="color:#48b685">&#39;age&#39;</span>, <span style="color:#48b685">&#39;_2&#39;</span><span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h4 id="attributs-spéciaux">Attributs Spéciaux</h4>
<p><code>namedtuple</code> fournit de nombreux attributs et méthodes pratiques pour travailler avec les sous-classes et les instances. Toutes ces propriétés natives ont des noms préfixés avec un tiret bas (<code>_</code>), qui par convention dans la plupart des programmes Python indique un attribut privé. Pour <code>namedtuple</code>, cependant, le préfixe est intentionnel pour protéger le nom d&rsquo;une collision avec les noms d&rsquo;attributs fournis par utilisateur.</p>
<p>Les noms de ces champs passés à <code>namedtuple</code> pour définir de nouvelle classe sont sauvegardés sont l&rsquo;attribut <code>_fields</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_fields.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Person <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>bob <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">30</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Representation:&#39;</span>, bob)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Fields:&#39;</span>, bob<span style="color:#5bc4bf">.</span>_fields)
</span></span></code></pre></div><p>Bien que l&rsquo;argument soit une seule chaîne séparée par des espaces, la valeur enregistrée est la séquence de noms individuels.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_fields.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Representation: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>30<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Fields: <span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;name&#39;</span>, <span style="color:#48b685">&#39;age&#39;</span><span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Les instances <code>namedtuple</code> peuvent être converties en instances <code>OrderedDict</code> par l&rsquo;usage de <code>_asdict()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_asdict.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Person <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>bob <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">30</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Representation:&#39;</span>, bob)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;As Dictionary:&#39;</span>, bob<span style="color:#5bc4bf">.</span>_asdict())
</span></span></code></pre></div><p>Les clés de <code>OrderedDict</code> sont dans le même ordre que les champs du <code>namedtuple</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_asdict.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Representation: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>30<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>As Dictionary: OrderedDict<span style="color:#5bc4bf">([(</span><span style="color:#48b685">&#39;name&#39;</span>, <span style="color:#48b685">&#39;Bob&#39;</span><span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;age&#39;</span>, 30<span style="color:#5bc4bf">)])</span>
</span></span></code></pre></div><p>La méthode <code>_replace()</code> construit une nouvelle instance, en remplaçant les valeur de certains champs dans le processus.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_namedtuple_replace.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Person <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>namedtuple(<span style="color:#48b685">&#39;Person&#39;</span>, <span style="color:#48b685">&#39;name age&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>bob <span style="color:#5bc4bf">=</span> Person(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, age<span style="color:#5bc4bf">=</span><span style="color:#f99b15">30</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Before:&#39;</span>, bob)
</span></span><span style="display:flex;"><span>bob2 <span style="color:#5bc4bf">=</span> bob<span style="color:#5bc4bf">.</span>_replace(name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Robert&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;After:&#39;</span>, bob2)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Same?:&#39;</span>, bob <span style="color:#5bc4bf">is</span> bob2)
</span></span></code></pre></div><p>Bien que le nom implique que l&rsquo;objet existant ait été modifié, parce que les instances <code>namedtuple</code> sont immuables, la méthode retourne actuellement un nouvel objet.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_namedtuple_replace.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Before: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Bob&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>30<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>After: Person<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;Robert&#39;</span>, <span style="color:#ef6155">age</span><span style="color:#5bc4bf">=</span>30<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Same?: False
</span></span></code></pre></div><h3 id="ordereddict---se-souvenir-de-lordre-des-clés-ajoutées-à-un-dictionnaire">OrderedDict - Se souvenir de l&rsquo;ordre des clés ajoutées à un dictionnaire</h3>
<p>Un <code>OrderedDict</code> est une sous-classe de dictionnaire qui se souvient de l&rsquo;ordre dans lequel son contenu est ajouté.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_ordereddict_iter.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Regular dictionary:&#39;</span>)
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> {}
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> d<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(k, v)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">OrderedDict:&#39;</span>)
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>OrderedDict()
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> d<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(k, v)
</span></span></code></pre></div><p>Avant Python 3.6 un <code>dict</code> ordinaire ne piste pas l&rsquo;ordre d&rsquo;insertion, et itère dessus les valeurs produites dans l&rsquo;ordre en fonction de la manière dont les clés étaient stockées dans la table de hachage, qui à son tour, est influencé par une valeur aléatoire pour réduire les collisions. Dans un <code>OrderedDict</code>, par contraste, l&rsquo;ordre dans lequel les éléments sont insérés est retenu et utilisé lors de la création de l&rsquo;itérateur.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3.5 collections_ordereddict_iter.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Regular dictionary:
</span></span><span style="display:flex;"><span>c C
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OrderedDict:
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>c C
</span></span></code></pre></div><p>Sous Python 3.6, le natif <code>dict</code> piste l&rsquo;ordre d&rsquo;insertion, bien que ce comportement soit l’un des effets secondaires d’un changement d’implémentation, il ne faut pas s&rsquo;y fier.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3.6 collections_ordereddict_iter.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Regular dictionary:
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>c C
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OrderedDict:
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>c C
</span></span></code></pre></div><h4 id="égalité">Égalité</h4>
<p>Un <code>dict</code> ordinaire cherche son contenu lorsqu&rsquo;il teste l&rsquo;égalité. Un <code>OrderedDict</code> considère lui aussi l&rsquo;ordre dans lequel les items sont ajoutés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_ordereddict_equality.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;dict       :&#39;</span>, end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>d1 <span style="color:#5bc4bf">=</span> {}
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d2 <span style="color:#5bc4bf">=</span> {}
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(d1 <span style="color:#5bc4bf">==</span> d2)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;OrderedDict:&#39;</span>, end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d1 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>OrderedDict()
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d1[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d2 <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>OrderedDict()
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;c&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;C&#39;</span>
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;b&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;B&#39;</span>
</span></span><span style="display:flex;"><span>d2[<span style="color:#48b685">&#39;a&#39;</span>] <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;A&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(d1 <span style="color:#5bc4bf">==</span> d2)
</span></span></code></pre></div><p>Dans ce cas, puisque deux dictionnaires ordonnés sont créés depuis des valeurs dans un ordre différent, ils sont considérés différents.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_ordereddict_equality.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>dict       : True
</span></span><span style="display:flex;"><span>OrderedDict: False
</span></span></code></pre></div><h4 id="réordonner-1">Réordonner</h4>
<p>Il est possible de changer l&rsquo;ordre des clés dans un <code>OrderedDict</code> en les bougeant selon le début ou la fin de la séquence en utilisant <code>move_to_end()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># collections_ordereddict_move_to_end.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">collections</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d <span style="color:#5bc4bf">=</span> collections<span style="color:#5bc4bf">.</span>OrderedDict(
</span></span><span style="display:flex;"><span>    [(<span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>), (<span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>), (<span style="color:#48b685">&#39;c&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>)]
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Before:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> d<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(k, v)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d<span style="color:#5bc4bf">.</span>move_to_end(<span style="color:#48b685">&#39;b&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">move_to_end():&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> d<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(k, v)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>d<span style="color:#5bc4bf">.</span>move_to_end(<span style="color:#48b685">&#39;b&#39;</span>, last<span style="color:#5bc4bf">=</span><span style="color:#815ba4">False</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">move_to_end(last=False):&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> d<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>    print(k, v)
</span></span></code></pre></div><p>Le dernier argument demande à <code>move_to_end()</code> de bouger l&rsquo;élément afin de devenir le dernier dans la séquence de clé (quand <code>True</code>) ou le premier (quand <code>False</code>).</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 collections_ordereddict_move_to_end.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Before:
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>c C
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>move_to_end<span style="color:#5bc4bf">()</span>:
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>c C
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>move_to_end<span style="color:#5bc4bf">(</span><span style="color:#ef6155">last</span><span style="color:#5bc4bf">=</span>False<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>b B
</span></span><span style="display:flex;"><span>a A
</span></span><span style="display:flex;"><span>c C
</span></span></code></pre></div><h4 id="lire-aussi-4">Lire aussi</h4>
<ul>
<li><a href="https://docs.python.org/fr/3.7/using/cmdline.html#envvar-PYTHONHASHSEED" rel="external">Variable d&rsquo;environnement pour contrôler la graine aléatoire de la valeur de l&rsquo;algorithme de hachage pour les positions des clés dans le dictionnaire</a></li>
</ul>
<h3 id="collectionsabc---classes-de-base-abstraites-pour-les-conteneurs">collections.abc - Classes de base abstraites pour les conteneurs</h3>
<p><strong>But</strong> : Classes de bases abstraites pour types de données de conteneur.</p>
<p>Le module <code>collections.abc</code> contient des classes de base abstraites qui définissent les API pour les structures de conteneur de données natives dans Python et fournies dans le module <code>collections</code>. Référez-vous à la table ci-dessous pour la liste des classes et leur but.</p>
<table>
  <thead>
      <tr>
          <th>Classe</th>
          <th>Classe(s) de Base</th>
          <th>But de l&rsquo;API</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Container</td>
          <td></td>
          <td>Fonctionnalités de base de conteneur, tel que l&rsquo;opérateur <code>inc</code>.</td>
      </tr>
      <tr>
          <td>Hashable</td>
          <td></td>
          <td>Ajoute le support de fourniture d&rsquo;une valeur de hachage pour l&rsquo;instance du conteneur.</td>
      </tr>
      <tr>
          <td>Iterable</td>
          <td></td>
          <td>Peut créer un itérateur sur le contenu du conteneur.</td>
      </tr>
      <tr>
          <td>Iterator</td>
          <td>Iterable</td>
          <td>Est un itérateur sur le contenu du conteneur.</td>
      </tr>
      <tr>
          <td>Generator</td>
          <td>Iterator</td>
          <td>Étend les itérateurs avec le protocole générateur du PEP 342.</td>
      </tr>
      <tr>
          <td>Sized</td>
          <td></td>
          <td>Ajoute les méthodes de conteneurs pour connaître la grosseur de leur taille.</td>
      </tr>
      <tr>
          <td>Callable</td>
          <td></td>
          <td>Pour les conteneurs invoqués en tant que fonction.</td>
      </tr>
      <tr>
          <td>Sequence</td>
          <td>Sized, Iterable, Container</td>
          <td>Prend en charge la récupération d&rsquo;éléments individuels, l&rsquo;itération et la modification de l&rsquo;ordre des éléments.</td>
      </tr>
      <tr>
          <td>MutableSequence</td>
          <td>Sequence</td>
          <td>Prend en charge l&rsquo;ajout et la suppression des éléments d&rsquo;une instance après qu&rsquo;ils soient créés.</td>
      </tr>
      <tr>
          <td>ByteString</td>
          <td>Sequence</td>
          <td>API combinées de <code>bytes</code> et de <code>bytearray</code>.</td>
      </tr>
      <tr>
          <td>Set</td>
          <td>Sized, Iterable, Container</td>
          <td>Prend en charges les opérations d&rsquo;ensemble telles que l&rsquo;intersection et l&rsquo;union.</td>
      </tr>
      <tr>
          <td>MutableSet</td>
          <td>Set</td>
          <td>Ajoute les méthodes de manipulation pour le contenu d&rsquo;ensemble après qu&rsquo;il soit créé.</td>
      </tr>
      <tr>
          <td>Mapping</td>
          <td>Sized, Iterable, Container</td>
          <td>Définit l&rsquo;API en lecture seule utilisé par <code>dict</code>.</td>
      </tr>
      <tr>
          <td>MutableMapping</td>
          <td>Mapping</td>
          <td>Définit les méthodes de manipulation des contenus pour la correspondance après qu&rsquo;ils soient créés.</td>
      </tr>
      <tr>
          <td>MappingView</td>
          <td>Sized</td>
          <td>Définit la vue de l&rsquo;API pour l’accès à la correspondance depuis un itérateur.</td>
      </tr>
      <tr>
          <td>ItemsView</td>
          <td>MappingView, Set</td>
          <td>Partie de la vue de l&rsquo;API.</td>
      </tr>
      <tr>
          <td>KeysView</td>
          <td>MappingView, Set</td>
          <td>Partie de la vue de l&rsquo;API.</td>
      </tr>
      <tr>
          <td>ValuesView</td>
          <td>MappingView</td>
          <td>Partie de la vue de l&rsquo;API.</td>
      </tr>
      <tr>
          <td>Awaitable</td>
          <td></td>
          <td>API pour les objets qui peuvent être utilisés dans des expressions <code>await</code>, telles que des coroutines.</td>
      </tr>
      <tr>
          <td>Coroutine</td>
          <td>Awaitable</td>
          <td>API pour les classes qui implémentent le protocole coroutine.</td>
      </tr>
      <tr>
          <td>AsyncIterable</td>
          <td></td>
          <td>API pour les itérables compatibles avec <code>async for</code>, telle que définit dans la PEP 492.</td>
      </tr>
      <tr>
          <td>AsyncIterator</td>
          <td>AsyncIterable</td>
          <td>API pour les itérateurs asynchrones.</td>
      </tr>
  </tbody>
</table>
<p>En plus de définir clairement les API pour les conteneurs avec des sémantiques différentes, ces classes de base abstraites peuvent être utilisées pour tester n&rsquo;importe quel objet qui prend en charge une API avant de l&rsquo;invoquer par l&rsquo;usage d&rsquo; <code>isinstance()</code>. Certaines de ces classes fournissent aussi des implémentations de méthodes, et elles peuvent être utilisées comme mixages(?) pour créer des types de conteneurs personnalisés sans implémenter chaque méthode à partir de rien.</p>
<h2 id="array---séquence-de-données-de-type-fixé">array - Séquence de Données de Type Fixé</h2>
<p><strong>But</strong> : Gérer efficacement des séquences de données numériques de type fixé.</p>
<p>Le module <code>array</code> définit une structure de données de séquence qui ressemble beaucoup à une <code>list</code>, excepté que tous les membres doivent être du même type primitif. Les types supportés sont tous les types numériques ou les autres primitifs de taille fixée, tels que les <code>bytes</code>.</p>
<p>Référez-vous à la table ci-dessous pour connaître certains des types supportés. La documentation de la bibliothèque standard pour <code>array</code> inclus une liste complète des codes de types.</p>
<table>
  <thead>
      <tr>
          <th>Code</th>
          <th>Type</th>
          <th>Taille minimal (octets)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>b</td>
          <td>int</td>
          <td>1</td>
      </tr>
      <tr>
          <td>B</td>
          <td>int</td>
          <td>1</td>
      </tr>
      <tr>
          <td>h</td>
          <td>signed short</td>
          <td>2</td>
      </tr>
      <tr>
          <td>H</td>
          <td>unsigned short</td>
          <td>2</td>
      </tr>
      <tr>
          <td>i</td>
          <td>signed int</td>
          <td>2</td>
      </tr>
      <tr>
          <td>I</td>
          <td>unsigned int</td>
          <td>2</td>
      </tr>
      <tr>
          <td>l</td>
          <td>signed long</td>
          <td>4</td>
      </tr>
      <tr>
          <td>L</td>
          <td>unsigned long</td>
          <td>4</td>
      </tr>
      <tr>
          <td>q</td>
          <td>signed long long</td>
          <td>8</td>
      </tr>
      <tr>
          <td>Q</td>
          <td>unsigned long long</td>
          <td>8</td>
      </tr>
      <tr>
          <td>f</td>
          <td>float</td>
          <td>4</td>
      </tr>
      <tr>
          <td>d</td>
          <td>double float</td>
          <td>8</td>
      </tr>
  </tbody>
</table>
<h3 id="initialisation-1">Initialisation</h3>
<p>Un <code>array</code> est instancié avec un argument décrivant le type de donnée à allouer, et si possible une séquence initiale de données à enregistrer dans le tableau.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># array_string.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>s <span style="color:#5bc4bf">=</span> <span style="color:#48b685">b</span><span style="color:#48b685">&#39;This is the array.&#39;</span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;b&#39;</span>, s)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;As byte string:&#39;</span>, s)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;As array      :&#39;</span>, a)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;As hex        :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(a))
</span></span></code></pre></div><p>Dans cet exemple, le tableau est configuré pour capturer une séquence d&rsquo;octets et est initialisé avec une simple chaîne d&rsquo;octets.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 array_string.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>As byte string: b<span style="color:#48b685">&#39;This is the array.&#39;</span>
</span></span><span style="display:flex;"><span>As array      : array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#5bc4bf">[</span>84, 104, 105, 115, 32, 105, 115, 32,
</span></span><span style="display:flex;"><span> 116, 104, 101, 32, 97, 114, 114, 97, 121, 46<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>As hex        : b<span style="color:#48b685">&#39;54686973206973207468652061727261792e&#39;</span>
</span></span></code></pre></div><h3 id="manipuler-des-tableaux">Manipuler des Tableaux</h3>
<p>Un <code>array</code> peut être étendu ou autrement manipulé de la même manière que les autres séquences Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># array_sequence.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">pprint</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>, range(<span style="color:#f99b15">3</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Initial :&#39;</span>, a)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a<span style="color:#5bc4bf">.</span>extend(range(<span style="color:#f99b15">3</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Extended:&#39;</span>, a)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Slice   :&#39;</span>, a[<span style="color:#f99b15">2</span>:<span style="color:#f99b15">5</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Iterator:&#39;</span>)
</span></span><span style="display:flex;"><span>print(list(enumerate(a)))
</span></span></code></pre></div><p>Les opérations supportées incluent le découpage, l&rsquo;itération, et l&rsquo;ajout d&rsquo;éléments à la fin.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 array_sequence.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Initial : array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Extended: array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2, 0, 1, 2<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Slice   : array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>2, 0, 1<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Iterator:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>0, 0<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>1, 1<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>2, 2<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>3, 0<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>4, 1<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>5, 2<span style="color:#5bc4bf">)]</span>
</span></span></code></pre></div><h3 id="tableaux-et-fichiers">Tableaux et Fichiers</h3>
<p>Le contenu d&rsquo;un tableau peut être écrit et lit depuis et vers des fichiers en utilisant des méthodes natives codées efficacement dans ce but.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># array_file.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">tempfile</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>, range(<span style="color:#f99b15">5</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;A1:&#39;</span>, a)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Write the array of numbers to a temporary file</span>
</span></span><span style="display:flex;"><span>output <span style="color:#5bc4bf">=</span> tempfile<span style="color:#5bc4bf">.</span>NamedTemporaryFile()
</span></span><span style="display:flex;"><span>a<span style="color:#5bc4bf">.</span>tofile(output<span style="color:#5bc4bf">.</span>file)  <span style="color:#776e71"># must pass an *actual* file</span>
</span></span><span style="display:flex;"><span>output<span style="color:#5bc4bf">.</span>flush()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Read the raw data</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">with</span> open(output<span style="color:#5bc4bf">.</span>name, <span style="color:#48b685">&#39;rb&#39;</span>) <span style="color:#815ba4">as</span> input:
</span></span><span style="display:flex;"><span>    raw_data <span style="color:#5bc4bf">=</span> input<span style="color:#5bc4bf">.</span>read()
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;Raw Contents:&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(raw_data))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># Read the data into an array</span>
</span></span><span style="display:flex;"><span>    input<span style="color:#5bc4bf">.</span>seek(<span style="color:#f99b15">0</span>)
</span></span><span style="display:flex;"><span>    a2 <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>)
</span></span><span style="display:flex;"><span>    a2<span style="color:#5bc4bf">.</span>fromfile(input, len(a))
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;A2:&#39;</span>, a2)
</span></span></code></pre></div><p>Cet exemple illustre la lecture de donnée «brute», venant directement depuis le fichier binaire, versus la lecture dans un autre tableau et convertissant les octets dans les types appropriés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 array_file.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>A1: array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2, 3, 4<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Raw Contents: b<span style="color:#48b685">&#39;0000000001000000020000000300000004000000&#39;</span>
</span></span><span style="display:flex;"><span>A2: array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2, 3, 4<span style="color:#5bc4bf">])</span>
</span></span></code></pre></div><p><code>tofile()</code> utilise <code>tobytes()</code> pour formater les données, et <code>fromfile()</code> utilise <code>frombytes()</code> pour les convertir à nouveau en une instance de tableau.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># array_tobytes.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>, range(<span style="color:#f99b15">5</span>))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;A1:&#39;</span>, a)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>as_bytes <span style="color:#5bc4bf">=</span> a<span style="color:#5bc4bf">.</span>tobytes()
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Bytes:&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(as_bytes))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a2 <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>)
</span></span><span style="display:flex;"><span>a2<span style="color:#5bc4bf">.</span>frombytes(as_bytes)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;A2:&#39;</span>, a2)
</span></span></code></pre></div><p>Les deux fonctions <code>tobytes()</code> et <code>frombytes()</code> fonctionnent sur des chaînes d&rsquo;octets, et non pas des chaînes Unicode.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 array_tobytes.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>A1: array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2, 3, 4<span style="color:#5bc4bf">])</span>
</span></span><span style="display:flex;"><span>Bytes: b<span style="color:#48b685">&#39;0000000001000000020000000300000004000000&#39;</span>
</span></span><span style="display:flex;"><span>A2: array<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;i&#39;</span>, <span style="color:#5bc4bf">[</span>0, 1, 2, 3, 4<span style="color:#5bc4bf">])</span>
</span></span></code></pre></div><h3 id="ordre-alternatif-doctet">Ordre Alternatif d&rsquo;Octet</h3>
<p>Si la donnée dans le tableau n&rsquo;est pas de l&rsquo;ordre natif d&rsquo;octet, ou si la donnée nécessite d&rsquo;être échangée avant d&rsquo;être envoyée au système avec un ordre d&rsquo;octet différent (ou sur le réseau), il est possible de convertir un tableau entier sans itérer les éléments dans Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># array_byteswap.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">to_hex</span>(a):
</span></span><span style="display:flex;"><span>    chars_per_item <span style="color:#5bc4bf">=</span> a<span style="color:#5bc4bf">.</span>itemsize <span style="color:#5bc4bf">*</span> <span style="color:#f99b15">2</span>  <span style="color:#776e71"># 2 hex digits</span>
</span></span><span style="display:flex;"><span>    hex_version <span style="color:#5bc4bf">=</span> binascii<span style="color:#5bc4bf">.</span>hexlify(a)
</span></span><span style="display:flex;"><span>    num_chunks <span style="color:#5bc4bf">=</span> len(hex_version) <span style="color:#5bc4bf">//</span> chars_per_item
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(num_chunks):
</span></span><span style="display:flex;"><span>        start <span style="color:#5bc4bf">=</span> i <span style="color:#5bc4bf">*</span> chars_per_item
</span></span><span style="display:flex;"><span>        end <span style="color:#5bc4bf">=</span> start <span style="color:#5bc4bf">+</span> chars_per_item
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">yield</span> hex_version[start:end]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>start <span style="color:#5bc4bf">=</span> int(<span style="color:#48b685">&#39;0x12345678&#39;</span>, <span style="color:#f99b15">16</span>)
</span></span><span style="display:flex;"><span>end <span style="color:#5bc4bf">=</span> start <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>a1 <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>, range(start, end))
</span></span><span style="display:flex;"><span>a2 <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;i&#39;</span>, range(start, end))
</span></span><span style="display:flex;"><span>a2<span style="color:#5bc4bf">.</span>byteswap()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>fmt <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:&gt;12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{:&gt;12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{:&gt;12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{:&gt;12}</span><span style="color:#48b685">&#39;</span>
</span></span><span style="display:flex;"><span>print(fmt<span style="color:#5bc4bf">.</span>format(<span style="color:#48b685">&#39;A1 hex&#39;</span>, <span style="color:#48b685">&#39;A1&#39;</span>, <span style="color:#48b685">&#39;A2 hex&#39;</span>, <span style="color:#48b685">&#39;A2&#39;</span>))
</span></span><span style="display:flex;"><span>print(fmt<span style="color:#5bc4bf">.</span>format(<span style="color:#48b685">&#39;-&#39;</span> <span style="color:#5bc4bf">*</span> <span style="color:#f99b15">12</span>, <span style="color:#48b685">&#39;-&#39;</span> <span style="color:#5bc4bf">*</span> <span style="color:#f99b15">12</span>, <span style="color:#48b685">&#39;-&#39;</span> <span style="color:#5bc4bf">*</span> <span style="color:#f99b15">12</span>, <span style="color:#48b685">&#39;-&#39;</span> <span style="color:#5bc4bf">*</span> <span style="color:#f99b15">12</span>))
</span></span><span style="display:flex;"><span>fmt <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;</span><span style="color:#f99b15">{!r:&gt;12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{:12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{!r:&gt;12}</span><span style="color:#48b685"> </span><span style="color:#f99b15">{:12}</span><span style="color:#48b685">&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> values <span style="color:#5bc4bf">in</span> zip(to_hex(a1), a1, to_hex(a2), a2):
</span></span><span style="display:flex;"><span>    print(fmt<span style="color:#5bc4bf">.</span>format(<span style="color:#5bc4bf">*</span>values))
</span></span></code></pre></div><p>La méthode <code>byteswap()</code> échange l&rsquo;ordre d&rsquo;octet des éléments dans le tableau depuis le langage C, qui est plus efficace pour boucler sur les données en Python.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 array_byteswap.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      A1 hex           A1       A2 hex           A2
</span></span><span style="display:flex;"><span>-------- -------- -------- --------
</span></span><span style="display:flex;"><span> b<span style="color:#48b685">&#39;78563412&#39;</span>    <span style="color:#f99b15">305419896</span>  b<span style="color:#48b685">&#39;12345678&#39;</span>   <span style="color:#f99b15">2018915346</span>
</span></span><span style="display:flex;"><span> b<span style="color:#48b685">&#39;79563412&#39;</span>    <span style="color:#f99b15">305419897</span>  b<span style="color:#48b685">&#39;12345679&#39;</span>   <span style="color:#f99b15">2035692562</span>
</span></span><span style="display:flex;"><span> b<span style="color:#48b685">&#39;7a563412&#39;</span>    <span style="color:#f99b15">305419898</span>  b<span style="color:#48b685">&#39;1234567a&#39;</span>   <span style="color:#f99b15">2052469778</span>
</span></span><span style="display:flex;"><span> b<span style="color:#48b685">&#39;7b563412&#39;</span>    <span style="color:#f99b15">305419899</span>  b<span style="color:#48b685">&#39;1234567b&#39;</span>   <span style="color:#f99b15">2069246994</span>
</span></span><span style="display:flex;"><span> b<span style="color:#48b685">&#39;7c563412&#39;</span>    <span style="color:#f99b15">305419900</span>  b<span style="color:#48b685">&#39;1234567c&#39;</span>   <span style="color:#f99b15">2086024210</span>
</span></span></code></pre></div><h3 id="lire-aussi-5">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/array.html" rel="external">Documentation de la bibliothèque standard pour <code>array</code></a></li>
<li><a href="/fr/trad/developpez.net/pymotw3-structures-de-donnees/#module-struct">struct</a> - Le module <code>struct</code>.</li>
<li><a href="https://www.numpy.org/" rel="external">Python Numérique</a> - NumPy est une bibliothèque Python pour travailler efficacement avec de grands ensembles de données.</li>
<li><a>Notes de Portage de Python 2 vers 3 sur array</a></li>
</ul>
<h2 id="heapq---algorithme-de-tri-heap">heapq - Algorithme de Tri Heap</h2>
<p><strong>But</strong> : Heapq implémente un algorithme de tri minitas(?) approprié pour utiliser les listes Python.</p>
<p>Un <code>heap</code> est tel une arborescence de structure de données dans laquelle les nœuds enfants ont une relation d&rsquo;ordre trié avec les nœuds parents. Le <code>binary heaps</code> peut être représenté en utilisant une liste ou un tableau organisé afin que les nœuds enfants d&rsquo;élément <code>N</code> soient à la position 2 * <em>N</em> + 1 et 2 * <em>N</em> + 2 (pour les index basés sur zéro). Ce calque rend cela possible en réarrangeant le tas en place, ainsi il est n&rsquo;est pas nécessaire de ré-allouer beaucoup de mémoire lors de l&rsquo;ajout ou de la suppression d&rsquo;items.</p>
<p>Un max-heap s&rsquo;assure que le nœud parent est plus large que ou égal à deux de ces enfants. Un min-heap requiert que le nœud parent soit plus petit ou égal à ces nœuds enfants. Le module Python <code>heapq</code> implémente un min-heap.</p>
<h3 id="exemple-de-donnée">Exemple de Donnée</h3>
<p>Cet exemple dans ce chapitre utilise la donnée dans le script <code>heapq_heapdata.py</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_heapdata.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># This data was generated with the random module.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>data <span style="color:#5bc4bf">=</span> [<span style="color:#f99b15">19</span>, <span style="color:#f99b15">9</span>, <span style="color:#f99b15">4</span>, <span style="color:#f99b15">10</span>, <span style="color:#f99b15">11</span>]
</span></span></code></pre></div><p>La sortie du tas est imprimé en utilisant le script <code>heapq_showtree.py</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_showtree.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">math</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">io</span> <span style="color:#5bc4bf">import</span> StringIO
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">show_tree</span>(tree, total_width<span style="color:#5bc4bf">=</span><span style="color:#f99b15">36</span>, fill<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>):
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;&#34;&#34;Pretty-print a tree.&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    output <span style="color:#5bc4bf">=</span> StringIO()
</span></span><span style="display:flex;"><span>    last_row <span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">-</span><span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> i, n <span style="color:#5bc4bf">in</span> enumerate(tree):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> i:
</span></span><span style="display:flex;"><span>            row <span style="color:#5bc4bf">=</span> int(math<span style="color:#5bc4bf">.</span>floor(math<span style="color:#5bc4bf">.</span>log(i <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>)))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>            row <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> row <span style="color:#5bc4bf">!=</span> last_row:
</span></span><span style="display:flex;"><span>            output<span style="color:#5bc4bf">.</span>write(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>)
</span></span><span style="display:flex;"><span>        columns <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">**</span> row
</span></span><span style="display:flex;"><span>        col_width <span style="color:#5bc4bf">=</span> int(math<span style="color:#5bc4bf">.</span>floor(total_width <span style="color:#5bc4bf">/</span> columns))
</span></span><span style="display:flex;"><span>        output<span style="color:#5bc4bf">.</span>write(str(n)<span style="color:#5bc4bf">.</span>center(col_width, fill))
</span></span><span style="display:flex;"><span>        last_row <span style="color:#5bc4bf">=</span> row
</span></span><span style="display:flex;"><span>    print(output<span style="color:#5bc4bf">.</span>getvalue())
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;-&#39;</span> <span style="color:#5bc4bf">*</span> total_width)
</span></span><span style="display:flex;"><span>    print()
</span></span></code></pre></div><h3 id="créer-un-heap">Créer un Heap</h3>
<p>Il y a deux manières de base de créer un heap : <code>heappush()</code> et <code>heapify()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_heappush.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_showtree</span> <span style="color:#5bc4bf">import</span> show_tree
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_heapdata</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>heap <span style="color:#5bc4bf">=</span> []
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;random :&#39;</span>, data)
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> n <span style="color:#5bc4bf">in</span> data:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;add </span><span style="color:#f99b15">{:&gt;3}</span><span style="color:#48b685">:&#39;</span><span style="color:#5bc4bf">.</span>format(n))
</span></span><span style="display:flex;"><span>    heapq<span style="color:#5bc4bf">.</span>heappush(heap, n)
</span></span><span style="display:flex;"><span>    show_tree(heap)
</span></span></code></pre></div><p>Quand <code>heappush()</code> est utilisé, l&rsquo;ordre de tri du tas des éléments est maintenu lorsque de nouveaux éléments sont ajoutés à partir d&rsquo;une source de données.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_heappush.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>random : <span style="color:#5bc4bf">[</span>19, 9, 4, 10, 11<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>add  19:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>add   9:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>add   4:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">19</span>                <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>add  10:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">10</span>                <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>add  11:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">10</span>                <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">19</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span></code></pre></div><p>Si la donnée est toujours en mémoire, il est plus efficient d&rsquo;utiliser <code>heapify()</code> pour réarranger les items dans la liste.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_heapify.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_showtree</span> <span style="color:#5bc4bf">import</span> show_tree
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_heapdata</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;random    :&#39;</span>, data)
</span></span><span style="display:flex;"><span>heapq<span style="color:#5bc4bf">.</span>heapify(data)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;heapified :&#39;</span>)
</span></span><span style="display:flex;"><span>show_tree(data)
</span></span></code></pre></div><p>Le résultat d&rsquo;une construction d&rsquo;une liste dans un ordre heap, un item à la fois, est le même que le fait de construire une liste non ordonnée en appelant <code>heapify()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_heapify.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>random    : <span style="color:#5bc4bf">[</span>19, 9, 4, 10, 11<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>heapified :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">9</span>                 <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">10</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span></code></pre></div><h3 id="accéder-au-contenu-dun-heap">Accéder au Contenu d&rsquo;un Heap</h3>
<p>Une fois que le heap est organisé correctement, utilisez <code>heappop()</code> pour supprimer l&rsquo;élément ayant la valeur la plus petite.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_heappop.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_showtree</span> <span style="color:#5bc4bf">import</span> show_tree
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_heapdata</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;random    :&#39;</span>, data)
</span></span><span style="display:flex;"><span>heapq<span style="color:#5bc4bf">.</span>heapify(data)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;heapified :&#39;</span>)
</span></span><span style="display:flex;"><span>show_tree(data)
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(<span style="color:#f99b15">2</span>):
</span></span><span style="display:flex;"><span>    smallest <span style="color:#5bc4bf">=</span> heapq<span style="color:#5bc4bf">.</span>heappop(data)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;pop    </span><span style="color:#f99b15">{:&gt;3}</span><span style="color:#48b685">:&#39;</span><span style="color:#5bc4bf">.</span>format(smallest))
</span></span><span style="display:flex;"><span>    show_tree(data)
</span></span></code></pre></div><p>Dans cet exemple, adapté de la documentation de la bibliothèque standard, <code>heapify()</code> et <code>heappop()</code> sont utilisées pour trier une liste de nombres.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_heappop.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>random    : <span style="color:#5bc4bf">[</span>19, 9, 4, 10, 11<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>heapified :
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">9</span>                 <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">10</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pop      4:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">10</span>                <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pop      9:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">10</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">11</span>                <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span></code></pre></div><p>Pour supprimer des éléments existants et les remplacer par de nouvelles valeurs en une unique opération, utilisez <code>heapreplace()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_heapreplace.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_showtree</span> <span style="color:#5bc4bf">import</span> show_tree
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_heapdata</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>heapq<span style="color:#5bc4bf">.</span>heapify(data)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;start:&#39;</span>)
</span></span><span style="display:flex;"><span>show_tree(data)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> n <span style="color:#5bc4bf">in</span> [<span style="color:#f99b15">0</span>, <span style="color:#f99b15">13</span>]:
</span></span><span style="display:flex;"><span>    smallest <span style="color:#5bc4bf">=</span> heapq<span style="color:#5bc4bf">.</span>heapreplace(data, n)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;replace </span><span style="color:#f99b15">{:&gt;2}</span><span style="color:#48b685"> with </span><span style="color:#f99b15">{:&gt;2}</span><span style="color:#48b685">:&#39;</span><span style="color:#5bc4bf">.</span>format(smallest, n))
</span></span><span style="display:flex;"><span>    show_tree(data)
</span></span></code></pre></div><p>Remplacer des éléments rend possible de maintenir un heap de taille fixée, tel qu&rsquo;une file de travaux ordonnés par priorité.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_heapreplace.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>start:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">9</span>                 <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">10</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>replace  <span style="color:#f99b15">4</span> with  0:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">9</span>                 <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">10</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>replace  <span style="color:#f99b15">0</span> with 13:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                 <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f99b15">10</span>                <span style="color:#f99b15">19</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">13</span>       <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>----------------------
</span></span></code></pre></div><h3 id="extrêmes-des-données-dun-heap">Extrêmes des Données d&rsquo;un Heap</h3>
<p><code>heapq</code> inclus aussi deux fonctions qui examine un itérable et trouve une rangée des valeurs les plus grandes ou les plus petites qu&rsquo;il contient.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_extremes.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">heapq_heapdata</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;all       :&#39;</span>, data)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;3 largest :&#39;</span>, heapq<span style="color:#5bc4bf">.</span>nlargest(<span style="color:#f99b15">3</span>, data))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;from sort :&#39;</span>, list(reversed(sorted(data)[<span style="color:#5bc4bf">-</span><span style="color:#f99b15">3</span>:])))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;3 smallest:&#39;</span>, heapq<span style="color:#5bc4bf">.</span>nsmallest(<span style="color:#f99b15">3</span>, data))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;from sort :&#39;</span>, sorted(data)[:<span style="color:#f99b15">3</span>])
</span></span></code></pre></div><p>Utiliser <code>nlargest()</code> et <code>nsmallest()</code> est efficace seulement pour les valeurs relativement petites de <em>n</em> &gt; 1, mais peut toujours devenir plus pratique dans quelques cas.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_extremes.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>all       : <span style="color:#5bc4bf">[</span>19, 9, 4, 10, 11<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">3</span> largest : <span style="color:#5bc4bf">[</span>19, 11, 10<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>from sort : <span style="color:#5bc4bf">[</span>19, 11, 10<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">3</span> smallest: <span style="color:#5bc4bf">[</span>4, 9, 10<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>from sort : <span style="color:#5bc4bf">[</span>4, 9, 10<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><h3 id="fusion-efficace-des-séquences-triées">Fusion Efficace des Séquences Triées</h3>
<p>Combiner de nombreuses séquences triées en une nouvelle séquence est facile pour de petits ensembles de données.</p>
<p><code>python list(sorted(itertools.chain(*data))) </code></p>
<p>Pour de plus grand ensembles de données, cette technique peut utiliser une somme considérable de mémoire. Au lieu de trier la séquence triée en entier, <code>merge()</code> utilise un tas pour générer un nouvelle séquence une à la fois, déterminant le nouvel item en utilisant une somme de mémoire fixée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># heapq_merge.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">heapq</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">random</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>random<span style="color:#5bc4bf">.</span>seed(<span style="color:#f99b15">2016</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>data <span style="color:#5bc4bf">=</span> []
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(<span style="color:#f99b15">4</span>):
</span></span><span style="display:flex;"><span>    new_data <span style="color:#5bc4bf">=</span> list(random<span style="color:#5bc4bf">.</span>sample(range(<span style="color:#f99b15">1</span>, <span style="color:#f99b15">101</span>), <span style="color:#f99b15">5</span>))
</span></span><span style="display:flex;"><span>    new_data<span style="color:#5bc4bf">.</span>sort()
</span></span><span style="display:flex;"><span>    data<span style="color:#5bc4bf">.</span>append(new_data)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i, d <span style="color:#5bc4bf">in</span> enumerate(data):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685">: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(i, d))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Merged:&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> heapq<span style="color:#5bc4bf">.</span>merge(<span style="color:#5bc4bf">*</span>data):
</span></span><span style="display:flex;"><span>    print(i, end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>print()
</span></span></code></pre></div><p>Puisque l&rsquo;implémentation de <code>merge()</code> utilise un tas, il consomme la mémoire basée sur le nombre de séquences à fusionner, plutôt que le nombre des éléments dans ces séquences.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 heapq_merge.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>0: <span style="color:#5bc4bf">[</span>33, 58, 71, 88, 95<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>1: <span style="color:#5bc4bf">[</span>10, 11, 17, 38, 91<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>2: <span style="color:#5bc4bf">[</span>13, 18, 39, 61, 63<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>3: <span style="color:#5bc4bf">[</span>20, 27, 31, 42, 45<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Merged:
</span></span><span style="display:flex;"><span><span style="color:#f99b15">10</span> <span style="color:#f99b15">11</span> <span style="color:#f99b15">13</span> <span style="color:#f99b15">17</span> <span style="color:#f99b15">18</span> <span style="color:#f99b15">20</span> <span style="color:#f99b15">27</span> <span style="color:#f99b15">31</span> <span style="color:#f99b15">33</span> <span style="color:#f99b15">38</span> <span style="color:#f99b15">39</span> <span style="color:#f99b15">42</span> <span style="color:#f99b15">45</span> <span style="color:#f99b15">58</span> <span style="color:#f99b15">61</span> <span style="color:#f99b15">63</span> <span style="color:#f99b15">71</span> <span style="color:#f99b15">88</span> <span style="color:#f99b15">91</span> <span style="color:#f99b15">95</span>
</span></span></code></pre></div><h3 id="lire-aussi-6">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/heapq.html" rel="external">Documentation de la bibliothèque standard pour heapq</a></li>
<li><a href="https://en.wikipedia.org/wiki/Heap_(data_structure)" rel="external">Wikipedia - Heap (structure de données)</a> - Une description générale des structures de données heap</li>
<li><a href="https://pymotw.com/3/queue/index.html#queue-priorityqueue" rel="external">Priorité de la File d&rsquo;attente</a> - Une implémentation prioritaire de la file d&rsquo;attente de <code>Queue</code> dans la bibliothèque standard.</li>
</ul>
<h2 id="bisect---maintenir-les-listes-dans-un-ordre-trié">bisect - Maintenir les Listes dans un Ordre Trié</h2>
<p><strong>But</strong> : Maintenir une liste dans un ordre trié sans avoir à appeler le tri chaque fois qu&rsquo;un item est ajouté à la liste.</p>
<p>Le module <code>bisect</code> implémente un algorithme pour insérer des éléments dans une liste tout en maintenant la liste dans un ordre trié.</p>
<h3 id="insérer-dans-un-ordre-trié">Insérer dans un Ordre Trié</h3>
<p>Voici un exemple dans lequel <code>insort()</code> est utilisé pour insérer des items dans la liste en ordre trié.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># bisect_example.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">bisect</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># A series of random numbers</span>
</span></span><span style="display:flex;"><span>values <span style="color:#5bc4bf">=</span> [<span style="color:#f99b15">14</span>, <span style="color:#f99b15">85</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">26</span>, <span style="color:#f99b15">50</span>, <span style="color:#f99b15">45</span>, <span style="color:#f99b15">66</span>, <span style="color:#f99b15">79</span>, <span style="color:#f99b15">10</span>, <span style="color:#f99b15">3</span>, <span style="color:#f99b15">84</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">1</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;New  Pos  Contents&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;---  ---  ------&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>l <span style="color:#5bc4bf">=</span> []
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> values:
</span></span><span style="display:flex;"><span>    position <span style="color:#5bc4bf">=</span> bisect<span style="color:#5bc4bf">.</span>bisect(l, i)
</span></span><span style="display:flex;"><span>    bisect<span style="color:#5bc4bf">.</span>insort(l, i)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:3}</span><span style="color:#48b685">  </span><span style="color:#f99b15">{:3}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(i, position), l)
</span></span></code></pre></div><p>La première colonne de sortie montre un nouveau nombre aléatoire. La seconde colonne montre la position où le nombre sera inséré dans la liste. Le reste de chaque ligne est la liste triée actuelle.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 bisect_example.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>New  Pos  Contents
</span></span><span style="display:flex;"><span>---  ---  ------
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">14</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>14<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">85</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">77</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">26</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 26, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">50</span>    <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">[</span>14, 26, 50, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">45</span>    <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">66</span>    <span style="color:#f99b15">4</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 66, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">79</span>    <span style="color:#f99b15">6</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">10</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>10, 14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">3</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">84</span>    <span style="color:#f99b15">9</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">77</span>    <span style="color:#f99b15">8</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">1</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><p>Ceci est un simple exemple. En fait, compte tenu de la quantité de données manipulées, il est plus rapide de simplifier la construction de la liste et la trier en une fois. Par contraste, pour des listes longues, des économies de temps et de mémoire considérables peuvent être obtenues à l&rsquo;aide d&rsquo;un algorithme de tri par insertion tel que celui-ci, spécialement quand l&rsquo;opération comparant deux membres d&rsquo;une liste requiert de coûteux calculs.</p>
<h3 id="traitement-des-doublons">Traitement des Doublons</h3>
<p>Le résultat de l&rsquo;ensemble montré précédemment inclus une valeur répétée, <code>77</code>. Le module <code>bisect</code> fournit deux manière de traiter les répétitions : les nouvelles valeurs peuvent être insérées soit à la gauche des valeurs existantes, soit à la droite. La fonction <code>insort()</code> est actuellement un alias de <code>insort_right()</code>, qui insère un item après une valeur existante. La fonction correspondante <code>insort_left()</code> insère un item avant la valeur existante.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># bisect_example2.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">bisect</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># A series of random numbers</span>
</span></span><span style="display:flex;"><span>values <span style="color:#5bc4bf">=</span> [<span style="color:#f99b15">14</span>, <span style="color:#f99b15">85</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">26</span>, <span style="color:#f99b15">50</span>, <span style="color:#f99b15">45</span>, <span style="color:#f99b15">66</span>, <span style="color:#f99b15">79</span>, <span style="color:#f99b15">10</span>, <span style="color:#f99b15">3</span>, <span style="color:#f99b15">84</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">1</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;New  Pos  Contents&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;---  ---  ------&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Use bisect_left and insort_left.</span>
</span></span><span style="display:flex;"><span>l <span style="color:#5bc4bf">=</span> []
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> values:
</span></span><span style="display:flex;"><span>    position <span style="color:#5bc4bf">=</span> bisect<span style="color:#5bc4bf">.</span>bisect_left(l, i)
</span></span><span style="display:flex;"><span>    bisect<span style="color:#5bc4bf">.</span>insort_left(l, i)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{:3}</span><span style="color:#48b685">  </span><span style="color:#f99b15">{:3}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(i, position), l)
</span></span></code></pre></div><p>Quand la même donnée est manipulée par l&rsquo;utilisation des fonctions <code>bisect_left()</code> et <code>insort_left()</code>, il en résulte la même liste triée mais l&rsquo;insertion des positions est différente pour les valeurs dupliquées.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 bisect_example2.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>New  Pos  Contents
</span></span><span style="display:flex;"><span>---  ---  ------
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">14</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>14<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">85</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">77</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">26</span>    <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">[</span>14, 26, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">50</span>    <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">[</span>14, 26, 50, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">45</span>    <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">66</span>    <span style="color:#f99b15">4</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 66, 77, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">79</span>    <span style="color:#f99b15">6</span> <span style="color:#5bc4bf">[</span>14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">10</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>10, 14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">3</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 79, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">84</span>    <span style="color:#f99b15">9</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> <span style="color:#f99b15">77</span>    <span style="color:#f99b15">7</span> <span style="color:#5bc4bf">[</span>3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f99b15">1</span>    <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">[</span>1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><h3 id="lire-aussi-7">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/bisect.html" rel="external">Documentation de la bibliothèque standard pour bisect</a></li>
<li><a href="https://en.wikipedia.org/wiki/Insertion_sort" rel="external">Wikipedia - Tri d&rsquo;insertion</a> - Une description de l&rsquo;algorithme d&rsquo;insertion de tri.</li>
</ul>
<h2 id="queue---implémentation-fifo-thread-safe">queue - Implémentation FIFO Thread-Safe</h2>
<p><strong>But</strong> : Fournir une implémentation FIFO de processus sûrs.</p>
<p>Le module <code>queue</code> fournit une structure de données premier entré, premier sorti (FIFO) adaptée à la programmation multithread. Elle peut être utilisée pour passer des messages ou d&rsquo;autres choses en toute sécurité entre les threads producteur et consommateur. Le verrouillage est géré pour l&rsquo;appelant. Ainsi, de nombreux threads peuvent fonctionner avec la même instance de <code>Queue</code> facilement et en toute sécurité. La taille de la <code>Queue</code> (le nombre des éléments qu&rsquo;elle contient) peut être restreinte à l&rsquo;utilisation ou au traitement de la mémoire.</p>
<blockquote>
<p><strong>Note</strong>
Cette discussion présume que vous comprenez la nature générale d&rsquo;une file d&rsquo;attente. Si ce n&rsquo;est pas le cas, vous devriez lire certaines références avant de continuer.</p>
</blockquote>
<h3 id="file-dattente-fifo-de-base">File d&rsquo;attente FIFO de base</h3>
<p>La classe <code>Queue</code> implémente un conteneur premier entré, premier sorti de base. Les éléments sont ajoutés à la «fin» de la séquence en utilisant la fonction <code>put()</code>, et supprimé à la fin d&rsquo;une autre par l&rsquo;utilisation de <code>get()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># queue_fifo.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">queue</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>q <span style="color:#5bc4bf">=</span> queue<span style="color:#5bc4bf">.</span>Queue()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(<span style="color:#f99b15">5</span>):
</span></span><span style="display:flex;"><span>    q<span style="color:#5bc4bf">.</span>put(i)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">while</span> <span style="color:#5bc4bf">not</span> q<span style="color:#5bc4bf">.</span>empty():
</span></span><span style="display:flex;"><span>    print(q<span style="color:#5bc4bf">.</span>get(), end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>print()
</span></span></code></pre></div><p>Cet exemple utilise un unique thread pour illustrer comment les éléments sont supprimés de la file d&rsquo;attente, dans le même ordre dans lequel ils ont été insérés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 queue_fifo.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">0</span> <span style="color:#f99b15">1</span> <span style="color:#f99b15">2</span> <span style="color:#f99b15">3</span> <span style="color:#f99b15">4</span>
</span></span></code></pre></div><h3 id="file-dattente-lifo">File d&rsquo;Attente LIFO</h3>
<p>Par contraste à l&rsquo;implémentation standard FIFO de <code>Queue</code>, la <code>LifoQueue</code> utilise l&rsquo;ordre dernier entré, premier sorti (normalement associé à la pile de la structure de données).</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># queue_lifo.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">queue</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>q <span style="color:#5bc4bf">=</span> queue<span style="color:#5bc4bf">.</span>LifoQueue()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(<span style="color:#f99b15">5</span>):
</span></span><span style="display:flex;"><span>    q<span style="color:#5bc4bf">.</span>put(i)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">while</span> <span style="color:#5bc4bf">not</span> q<span style="color:#5bc4bf">.</span>empty():
</span></span><span style="display:flex;"><span>    print(q<span style="color:#5bc4bf">.</span>get(), end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>print()
</span></span></code></pre></div><p>L&rsquo;élément le plus récemment entré dans la file d&rsquo;attente est supprimé par <code>get</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 queue_lifo.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">4</span> <span style="color:#f99b15">3</span> <span style="color:#f99b15">2</span> <span style="color:#f99b15">1</span> <span style="color:#f99b15">0</span>
</span></span></code></pre></div><h3 id="priorité-dans-la-file-dattente">Priorité dans la File d&rsquo;Attente</h3>
<p>Parfois, l&rsquo;ordre de traitement des éléments d&rsquo;une file d&rsquo;attente doit être basé sur les caractéristiques de ces éléments, plutôt que sur l&rsquo;ordre dans lequel ils ont été créés ou ajoutés à la file d&rsquo;attente. Par exemple, les travaux d&rsquo;impression du service de la comptabilité peuvent avoir priorité sur une liste de codes qu&rsquo;un développeur souhaite imprimer. <code>PriorityQueues</code> utilise l&rsquo;ordre de tri de la file d&rsquo;attente pour décider quel élément est à récupérer.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># queue_priority.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">functools</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">queue</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">threading</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">@functools.total_ordering</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">Job</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, priority, description):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>priority <span style="color:#5bc4bf">=</span> priority
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>description <span style="color:#5bc4bf">=</span> description
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;New job:&#39;</span>, description)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__eq__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>priority <span style="color:#5bc4bf">==</span> other<span style="color:#5bc4bf">.</span>priority
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">except</span> <span style="color:#ef6155">AttributeError</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> NotImplemented
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__lt__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">try</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>priority <span style="color:#5bc4bf">&lt;</span> other<span style="color:#5bc4bf">.</span>priority
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">except</span> <span style="color:#ef6155">AttributeError</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> NotImplemented
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>q <span style="color:#5bc4bf">=</span> queue<span style="color:#5bc4bf">.</span>PriorityQueue()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>q<span style="color:#5bc4bf">.</span>put(Job(<span style="color:#f99b15">3</span>, <span style="color:#48b685">&#39;Mid-level job&#39;</span>))
</span></span><span style="display:flex;"><span>q<span style="color:#5bc4bf">.</span>put(Job(<span style="color:#f99b15">10</span>, <span style="color:#48b685">&#39;Low-level job&#39;</span>))
</span></span><span style="display:flex;"><span>q<span style="color:#5bc4bf">.</span>put(Job(<span style="color:#f99b15">1</span>, <span style="color:#48b685">&#39;Important job&#39;</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">process_job</span>(q):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span>        next_job <span style="color:#5bc4bf">=</span> q<span style="color:#5bc4bf">.</span>get()
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;Processing job:&#39;</span>, next_job<span style="color:#5bc4bf">.</span>description)
</span></span><span style="display:flex;"><span>        q<span style="color:#5bc4bf">.</span>task_done()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>workers <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>    threading<span style="color:#5bc4bf">.</span>Thread(target<span style="color:#5bc4bf">=</span>process_job, args<span style="color:#5bc4bf">=</span>(q,)),
</span></span><span style="display:flex;"><span>    threading<span style="color:#5bc4bf">.</span>Thread(target<span style="color:#5bc4bf">=</span>process_job, args<span style="color:#5bc4bf">=</span>(q,)),
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> w <span style="color:#5bc4bf">in</span> workers:
</span></span><span style="display:flex;"><span>    w<span style="color:#5bc4bf">.</span>setDaemon(<span style="color:#815ba4">True</span>)
</span></span><span style="display:flex;"><span>    w<span style="color:#5bc4bf">.</span>start()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>q<span style="color:#5bc4bf">.</span>join()
</span></span></code></pre></div><p>Cet exemple comporte de multiples threads consommant les travaux, qui sont traités en fonction de la priorité des éléments dans la file d&rsquo;attente au moment où <code>get()</code> est appelé. L&rsquo;ordre de traitement des éléments ajoutés à la file d&rsquo;attente, pendant l&rsquo;exécution des threads consommateurs, dépend du basculement du contexte du thread.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 queue_priority.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>New job: Mid-level job
</span></span><span style="display:flex;"><span>New job: Low-level job
</span></span><span style="display:flex;"><span>New job: Important job
</span></span><span style="display:flex;"><span>Processing job: Important job
</span></span><span style="display:flex;"><span>Processing job: Mid-level job
</span></span><span style="display:flex;"><span>Processing job: Low-level job
</span></span></code></pre></div><h3 id="construire-un-thread-client-de-podcast">Construire un Thread Client de Podcast</h3>
<p>Le code source pour un client de podcast dans ce chapitre démontre comment utiliser la classe <code>Queue</code> avec de multiples threads. Le programme lit un ou plusieurs flux RSS, met en file d&rsquo;attente les pièces jointes des cinq derniers épisodes de chaque flux à télécharger et traite plusieurs téléchargements en parallèle à l&rsquo;aide de threads. La gestion des erreurs n’est pas suffisante pour une utilisation en production, mais l’implémentation du squelette illustre l’utilisation du module <code>queue</code>.</p>
<p>En premier, certains paramètres de fonctionnement sont établis. Habituellement, ce sont des entrées d&rsquo;utilisateur (p.ex. : des préférences ou d&rsquo;une base de données). L&rsquo;exemple utilise des valeurs codées en dur pour le nombre des threads et la liste des URL à récupérer.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># fetch_podcasts.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">queue</span> <span style="color:#5bc4bf">import</span> Queue
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">threading</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">time</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">urllib</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">urllib.parse</span> <span style="color:#5bc4bf">import</span> urlparse
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">feedparser</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Set up some global variables</span>
</span></span><span style="display:flex;"><span>num_fetch_threads <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>enclosure_queue <span style="color:#5bc4bf">=</span> Queue()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># A real app wouldn&#39;t use hard-coded data...</span>
</span></span><span style="display:flex;"><span>feed_urls <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#39;http://talkpython.fm/episodes/rss&#39;</span>,
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">message</span>(s):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">{}</span><span style="color:#48b685">: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(threading<span style="color:#5bc4bf">.</span>current_thread()<span style="color:#5bc4bf">.</span>name, s))
</span></span></code></pre></div><p>La fonction <code>download_enclosures()</code> s&rsquo;exécute dans le thread de travail et traite les téléchargements en utilisant <code>urllib</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">download_enclosures</span>(q):
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;&#34;&#34;This is the worker thread function.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    It processes items in the queue one after
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    another.  These daemon threads go into an
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    infinite loop, and exit only when
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    the main thread ends.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">while</span> <span style="color:#815ba4">True</span>:
</span></span><span style="display:flex;"><span>        message(<span style="color:#48b685">&#39;looking for the next enclosure&#39;</span>)
</span></span><span style="display:flex;"><span>        url <span style="color:#5bc4bf">=</span> q<span style="color:#5bc4bf">.</span>get()
</span></span><span style="display:flex;"><span>        filename <span style="color:#5bc4bf">=</span> url<span style="color:#5bc4bf">.</span>rpartition(<span style="color:#48b685">&#39;/&#39;</span>)[<span style="color:#5bc4bf">-</span><span style="color:#f99b15">1</span>]
</span></span><span style="display:flex;"><span>        message(<span style="color:#48b685">&#39;downloading </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(filename))
</span></span><span style="display:flex;"><span>        response <span style="color:#5bc4bf">=</span> urllib<span style="color:#5bc4bf">.</span>request<span style="color:#5bc4bf">.</span>urlopen(url)
</span></span><span style="display:flex;"><span>        data <span style="color:#5bc4bf">=</span> response<span style="color:#5bc4bf">.</span>read()
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># Save the downloaded file to the current directory</span>
</span></span><span style="display:flex;"><span>        message(<span style="color:#48b685">&#39;writing to </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(filename))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">with</span> open(filename, <span style="color:#48b685">&#39;wb&#39;</span>) <span style="color:#815ba4">as</span> outfile:
</span></span><span style="display:flex;"><span>            outfile<span style="color:#5bc4bf">.</span>write(data)
</span></span><span style="display:flex;"><span>        q<span style="color:#5bc4bf">.</span>task_done()
</span></span></code></pre></div><p>Une fois que la fonction cible pour les threads est définie, le thread de travail peut être démarré. Quand <code>download_enclosures()</code> s&rsquo;occupe de l&rsquo;instruction <code>url = q.get()</code>, elle la bloque et attend jusqu&rsquo;à ce que la file d&rsquo;attente ait quelque chose à retourner. Cela signifie qu&rsquo;il est prudent de démarrer les threads avant qu&rsquo;il n&rsquo;y ait quoi que ce soit dans la file d&rsquo;attente.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># Set up some threads to fetch the enclosures</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> i <span style="color:#5bc4bf">in</span> range(num_fetch_threads):
</span></span><span style="display:flex;"><span>    worker <span style="color:#5bc4bf">=</span> threading<span style="color:#5bc4bf">.</span>Thread(
</span></span><span style="display:flex;"><span>        target<span style="color:#5bc4bf">=</span>download_enclosures,
</span></span><span style="display:flex;"><span>        args<span style="color:#5bc4bf">=</span>(enclosure_queue,),
</span></span><span style="display:flex;"><span>        name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;worker-</span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(i),
</span></span><span style="display:flex;"><span>    )
</span></span><span style="display:flex;"><span>    worker<span style="color:#5bc4bf">.</span>setDaemon(<span style="color:#815ba4">True</span>)
</span></span><span style="display:flex;"><span>    worker<span style="color:#5bc4bf">.</span>start()
</span></span></code></pre></div><p>L&rsquo;étape suivante est de récupérer le contenu de flux en utilisant le module <code>feedparser</code> et de mettre en file d&rsquo;attente les URL. Dès que possible, la première URL est ajoutée à la file d&rsquo;attente, un des threads de travail la prend et démarre le téléchargement. La boucle continue d&rsquo;ajouter les éléments jusqu&rsquo;à ce que le flux soit complet, et les threads de travail retirent à tour de rôle de la file d&rsquo;attente les URL pour les télécharger.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># Download the feed(s) and put the enclosure URLs into</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># the queue.</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> url <span style="color:#5bc4bf">in</span> feed_urls:
</span></span><span style="display:flex;"><span>    response <span style="color:#5bc4bf">=</span> feedparser<span style="color:#5bc4bf">.</span>parse(url, agent<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;fetch_podcasts.py&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> entry <span style="color:#5bc4bf">in</span> response[<span style="color:#48b685">&#39;entries&#39;</span>][:<span style="color:#f99b15">5</span>]:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">for</span> enclosure <span style="color:#5bc4bf">in</span> entry<span style="color:#5bc4bf">.</span>get(<span style="color:#48b685">&#39;enclosures&#39;</span>, []):
</span></span><span style="display:flex;"><span>            parsed_url <span style="color:#5bc4bf">=</span> urlparse(enclosure[<span style="color:#48b685">&#39;url&#39;</span>])
</span></span><span style="display:flex;"><span>            message(<span style="color:#48b685">&#39;queuing </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(
</span></span><span style="display:flex;"><span>                parsed_url<span style="color:#5bc4bf">.</span>path<span style="color:#5bc4bf">.</span>rpartition(<span style="color:#48b685">&#39;/&#39;</span>)[<span style="color:#5bc4bf">-</span><span style="color:#f99b15">1</span>]))
</span></span><span style="display:flex;"><span>            enclosure_queue<span style="color:#5bc4bf">.</span>put(enclosure[<span style="color:#48b685">&#39;url&#39;</span>])
</span></span></code></pre></div><p>Il ne reste plus qu&rsquo;à attendre que la file se vide à nouveau, par l&rsquo;utilisation de <code>join()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># Now wait for the queue to be empty, indicating that we have</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># processed all of the downloads.</span>
</span></span><span style="display:flex;"><span>message(<span style="color:#48b685">&#39;*** main thread waiting&#39;</span>)
</span></span><span style="display:flex;"><span>enclosure_queue<span style="color:#5bc4bf">.</span>join()
</span></span><span style="display:flex;"><span>message(<span style="color:#48b685">&#39;*** done&#39;</span>)
</span></span></code></pre></div><p>L&rsquo;exécution de cet exemple de script produit une sortie similaire à celle qui suit.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>python3 fetch_podcasts.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>worker-0: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>worker-1: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>MainThread: queuing turbogears-and-the-future-of-python-web-frameworks.mp3
</span></span><span style="display:flex;"><span>MainThread: queuing continuum-scientific-python-and-the-business-of-open-source.mp3
</span></span><span style="display:flex;"><span>MainThread: queuing openstack-cloud-computing-built-on-python.mp3
</span></span><span style="display:flex;"><span>MainThread: queuing pypy.js-pypy-python-in-your-browser.mp3
</span></span><span style="display:flex;"><span>MainThread: queuing machine-learning-with-python-and-scikit-learn.mp3
</span></span><span style="display:flex;"><span>MainThread: *** main thread waiting
</span></span><span style="display:flex;"><span>worker-0: downloading turbogears-and-the-future-of-python-web-frameworks.mp3
</span></span><span style="display:flex;"><span>worker-1: downloading continuum-scientific-python-and-the-business-of-open-source.mp3
</span></span><span style="display:flex;"><span>worker-0: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>worker-0: downloading openstack-cloud-computing-built-on-python.mp3
</span></span><span style="display:flex;"><span>worker-1: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>worker-1: downloading pypy.js-pypy-python-in-your-browser.mp3
</span></span><span style="display:flex;"><span>worker-0: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>worker-0: downloading machine-learning-with-python-and-scikit-learn.mp3
</span></span><span style="display:flex;"><span>worker-1: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>worker-0: looking <span style="color:#815ba4">for</span> the next enclosure
</span></span><span style="display:flex;"><span>MainThread: *** <span style="color:#815ba4">done</span>
</span></span></code></pre></div><p>La sortie actuelle dépendra du contenu des flux RSS utilisés.</p>
<h3 id="lire-aussi-8">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/queue.html" rel="external">Documentation de la bibliothèque standard pour queue</a></li>
<li><a>deque - File d&rsquo;Attente Double</a> dans le chapitre <a>collections</a></li>
<li><a title="Queue data structures" href="https://en.wikipedia.org/wiki/Queue_(data_structure)" rel="external">Structures de Données en Files d&rsquo;Attente</a> - Un article Wikipédia en anglais expliquant les files d&rsquo;attentes.</li>
<li><a href="https://fr.wikipedia.org/wiki/File_(structure_de_donn%C3%A9es)" rel="external">FIFO</a> - Un article Wikipédia expliquant les structures de données, premier entré, premier sorti.</li>
<li><a href="https://pypi.python.org/pypi/feedparser" rel="external">module feedparser</a> - Un module pour analyser les flux RSS et Atom, créé par Mark Pilgrim et maintenu par Kurt McKee.</li>
</ul>
<h2 id="struct---structures-de-données-binaires">struct - Structures de Données Binaires</h2>
<p><strong>But</strong> : Conversion entre chaînes et données binaires.</p>
<p>Le module <code>struct</code> inclut des fonctions pour la conversion entre les octets de chaînes et les types de données Python natifs tels que les nombres et les chaînes.</p>
<h3 id="fonctions-versus-classe-struct">Fonctions versus Classe Struct</h3>
<p>Un ensemble de fonctions au niveau du module est disponible pour travailler avec des valeurs structurées, tout comme la classe <code>Struct</code>. Les spécificateurs de format sont convertis depuis leur format de chaînes vers une représentation compilée, similaire à la façon dont sont pratiques les expressions régulières. La conversion nécessite certaines ressources, ainsi il est plus efficient de la faire en une fois lors de la création de l&rsquo;instance <code>Struct</code> et de l&rsquo;appel des méthodes sur l&rsquo;instance plutôt que d&rsquo;utiliser les fonctions au niveau du module. Tous les exemples suivants utilisent la classe <code>Struct</code>.</p>
<h3 id="emballage-et-déballage">Emballage et Déballage</h3>
<p>Les structures prennent en charge l&rsquo;<em>emballage</em> de données dans les chaînes, et le <em>déballage</em> de données depuis les chaînes par l&rsquo;usage des spécificateurs de format composés de caractères représentant le type des données et d&rsquo;indicateurs facultatifs de comptage et de finalité. Se référer à la documentation standard de la bibliothèque pour avoir la liste complète des spécificateurs de format supportés.</p>
<p>Dans cet exemple, le spécificateur appelle comme valeurs, un entier, un entier long, et un nombre à virgule flottante. Les espaces dans le spécificateur de format sont inclus pour séparer le type d&rsquo;indicateurs, et sont ignorés lorsque le format est compilé.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># struct_pack.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">struct</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>values <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">1</span>, <span style="color:#48b685">&#39;ab&#39;</span><span style="color:#5bc4bf">.</span>encode(<span style="color:#48b685">&#39;utf-8&#39;</span>), <span style="color:#f99b15">2.7</span>)
</span></span><span style="display:flex;"><span>s <span style="color:#5bc4bf">=</span> struct<span style="color:#5bc4bf">.</span>Struct(<span style="color:#48b685">&#39;I 2s f&#39;</span>)
</span></span><span style="display:flex;"><span>packed_data <span style="color:#5bc4bf">=</span> s<span style="color:#5bc4bf">.</span>pack(<span style="color:#5bc4bf">*</span>values)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Original values:&#39;</span>, values)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Format string  :&#39;</span>, s<span style="color:#5bc4bf">.</span>format)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Uses           :&#39;</span>, s<span style="color:#5bc4bf">.</span>size, <span style="color:#48b685">&#39;bytes&#39;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Packed Value   :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(packed_data))
</span></span></code></pre></div><p>L&rsquo;exemple convertit la valeur encodée en une séquence d&rsquo;octets hexadécimaux pour l&rsquo;imprimer avec la fonction <code>binascii.hexlify()</code>, puisque certains des caractères sont nuls.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 struct_pack.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Original values: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.7<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Format string  : I 2s f
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">12</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;0100000061620000cdcc2c40&#39;</span>
</span></span></code></pre></div><p>Utilisez <code>unpack()</code> pour extraire la donnée de sa représentation encodée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># struct_unpack.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">struct</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>packed_data <span style="color:#5bc4bf">=</span> binascii<span style="color:#5bc4bf">.</span>unhexlify(<span style="color:#48b685">b</span><span style="color:#48b685">&#39;0100000061620000cdcc2c40&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>s <span style="color:#5bc4bf">=</span> struct<span style="color:#5bc4bf">.</span>Struct(<span style="color:#48b685">&#39;I 2s f&#39;</span>)
</span></span><span style="display:flex;"><span>unpacked_data <span style="color:#5bc4bf">=</span> s<span style="color:#5bc4bf">.</span>unpack(packed_data)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Unpacked Values:&#39;</span>, unpacked_data)
</span></span></code></pre></div><p>Passer la valeur condensée à <code>unpack()</code> renvoie les mêmes valeurs (notez l’écart dans la valeur à virgule flottante).</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 struct_unpack.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Unpacked Values: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="endianness">Endianness</h3>
<p>Par défaut, les valeurs sont codées à l&rsquo;aide de la notion d&rsquo;<em>endianness</em> de la bibliothèque C native. Il est facile de surcharger ce choix en fournissant une directive endianness explicite dans le format de chaînes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># struct_endianness.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">struct</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>values <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">1</span>, <span style="color:#48b685">&#39;ab&#39;</span><span style="color:#5bc4bf">.</span>encode(<span style="color:#48b685">&#39;utf-8&#39;</span>), <span style="color:#f99b15">2.7</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Original values:&#39;</span>, values)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>endianness <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;@&#39;</span>, <span style="color:#48b685">&#39;native, native&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;=&#39;</span>, <span style="color:#48b685">&#39;native, standard&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;&lt;&#39;</span>, <span style="color:#48b685">&#39;little-endian&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;&gt;&#39;</span>, <span style="color:#48b685">&#39;big-endian&#39;</span>),
</span></span><span style="display:flex;"><span>    (<span style="color:#48b685">&#39;!&#39;</span>, <span style="color:#48b685">&#39;network&#39;</span>),
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> code, name <span style="color:#5bc4bf">in</span> endianness:
</span></span><span style="display:flex;"><span>    s <span style="color:#5bc4bf">=</span> struct<span style="color:#5bc4bf">.</span>Struct(code <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39; I 2s f&#39;</span>)
</span></span><span style="display:flex;"><span>    packed_data <span style="color:#5bc4bf">=</span> s<span style="color:#5bc4bf">.</span>pack(<span style="color:#5bc4bf">*</span>values)
</span></span><span style="display:flex;"><span>    print()
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;Format string  :&#39;</span>, s<span style="color:#5bc4bf">.</span>format, <span style="color:#48b685">&#39;for&#39;</span>, name)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;Uses           :&#39;</span>, s<span style="color:#5bc4bf">.</span>size, <span style="color:#48b685">&#39;bytes&#39;</span>)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;Packed Value   :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(packed_data))
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;Unpacked Value :&#39;</span>, s<span style="color:#5bc4bf">.</span>unpack(packed_data))
</span></span></code></pre></div><p>La table ci-dessous liste les spécificateurs d&rsquo;ordre d&rsquo;octets utilisés par <code>Struct</code>.</p>
<table>
  <thead>
      <tr>
          <th>Code</th>
          <th>Signification</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>@</td>
          <td>Ordre natif</td>
      </tr>
      <tr>
          <td>=</td>
          <td>Standard natif</td>
      </tr>
      <tr>
          <td>&lt;</td>
          <td>little-endian</td>
      </tr>
      <tr>
          <td>&gt;</td>
          <td>big-endian</td>
      </tr>
      <tr>
          <td>!</td>
          <td>Ordre réseau</td>
      </tr>
  </tbody>
</table>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 struct_endianness.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Original values: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.7<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format string  : @ I 2s f <span style="color:#815ba4">for</span> native, native
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">12</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;0100000061620000cdcc2c40&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked Value : <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format string  : <span style="color:#5bc4bf">=</span> I 2s f <span style="color:#815ba4">for</span> native, standard
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">10</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;010000006162cdcc2c40&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked Value : <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format string  : &lt; I 2s f <span style="color:#815ba4">for</span> little-endian
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">10</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;010000006162cdcc2c40&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked Value : <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format string  : &gt; I 2s f <span style="color:#815ba4">for</span> big-endian
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">10</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;000000016162402ccccd&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked Value : <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format string  : ! I 2s f <span style="color:#815ba4">for</span> network
</span></span><span style="display:flex;"><span>Uses           : <span style="color:#f99b15">10</span> bytes
</span></span><span style="display:flex;"><span>Packed Value   : b<span style="color:#48b685">&#39;000000016162402ccccd&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked Value : <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="tampons">Tampons</h3>
<p>Travailler avec une donnée encodée en binaire est typiquement réservé pour les situations nécessitant de la performance ou de passer la donnée vers ou depuis des modules d&rsquo;extensions. Ces cas peuvent être optimisés en évitant la surcharge liée à l&rsquo;allocation d&rsquo;un nouveau tampon pour chaque structure codée. Les méthodes <code>pack_into()</code> et <code>unpack_from()</code> prennent en charge l&rsquo;écriture directe de tampons préalloués.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># struct_buffers.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">array</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">binascii</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">ctypes</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">struct</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>s <span style="color:#5bc4bf">=</span> struct<span style="color:#5bc4bf">.</span>Struct(<span style="color:#48b685">&#39;I 2s f&#39;</span>)
</span></span><span style="display:flex;"><span>values <span style="color:#5bc4bf">=</span> (<span style="color:#f99b15">1</span>, <span style="color:#48b685">&#39;ab&#39;</span><span style="color:#5bc4bf">.</span>encode(<span style="color:#48b685">&#39;utf-8&#39;</span>), <span style="color:#f99b15">2.7</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Original:&#39;</span>, values)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;ctypes string buffer&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> ctypes<span style="color:#5bc4bf">.</span>create_string_buffer(s<span style="color:#5bc4bf">.</span>size)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Before  :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(b<span style="color:#5bc4bf">.</span>raw))
</span></span><span style="display:flex;"><span>s<span style="color:#5bc4bf">.</span>pack_into(b, <span style="color:#f99b15">0</span>, <span style="color:#5bc4bf">*</span>values)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;After   :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(b<span style="color:#5bc4bf">.</span>raw))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Unpacked:&#39;</span>, s<span style="color:#5bc4bf">.</span>unpack_from(b, <span style="color:#f99b15">0</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;array&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> array<span style="color:#5bc4bf">.</span>array(<span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#48b685">b</span><span style="color:#48b685">&#39;</span><span style="color:#f99b15">\0</span><span style="color:#48b685">&#39;</span> <span style="color:#5bc4bf">*</span> s<span style="color:#5bc4bf">.</span>size)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Before  :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(a))
</span></span><span style="display:flex;"><span>s<span style="color:#5bc4bf">.</span>pack_into(a, <span style="color:#f99b15">0</span>, <span style="color:#5bc4bf">*</span>values)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;After   :&#39;</span>, binascii<span style="color:#5bc4bf">.</span>hexlify(a))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;Unpacked:&#39;</span>, s<span style="color:#5bc4bf">.</span>unpack_from(a, <span style="color:#f99b15">0</span>))
</span></span></code></pre></div><p>L&rsquo;attribut <code>size</code> à <code>Struct</code> nous dit la taille dont a besoin le tampon.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 struct_buffers.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Original: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.7<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ctypes string buffer
</span></span><span style="display:flex;"><span>Before  : b<span style="color:#48b685">&#39;000000000000000000000000&#39;</span>
</span></span><span style="display:flex;"><span>After   : b<span style="color:#48b685">&#39;0100000061620000cdcc2c40&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>array
</span></span><span style="display:flex;"><span>Before  : b<span style="color:#48b685">&#39;000000000000000000000000&#39;</span>
</span></span><span style="display:flex;"><span>After   : b<span style="color:#48b685">&#39;0100000061620000cdcc2c40&#39;</span>
</span></span><span style="display:flex;"><span>Unpacked: <span style="color:#5bc4bf">(</span>1, b<span style="color:#48b685">&#39;ab&#39;</span>, 2.700000047683716<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="lire-aussi-9">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/struct.html" rel="external">Documentation de la bibliothèque standard pour struct</a></li>
<li><a title="Python 2 to 3 porting notes for struct" href="https://pymotw.com/3/porting_notes.html#porting-struct" rel="external">Notes de portage de Python 2 vers 3 pour struct</a></li>
<li><a>array</a> - Le module <code>array</code>, pour travailler avec des séquences de valeurs de type fixé</li>
<li><code>binascii</code> - Le module <code>binascii</code>, pour produire des représentations ASCII de donnée binaire.</li>
<li><a title="Endianess : Boutisme" href="https://fr.wikipedia.org/wiki/Boutisme" rel="external">Wikipédia : Endianess</a></li>
</ul>
<h2 id="weakref---références-impermanentes-aux-objets">weakref - Références Impermanentes aux Objets</h2>
<p><strong>But</strong>: Référer un objet «coûteux», tout en permettant à sa mémoire d&rsquo;être réclamée par le ramasse miettes s&rsquo;il n&rsquo;y a pas d&rsquo;autres références non faibles.</p>
<p>Le module <code>weakref</code> prend en charge les références faibles aux objets. Une référence normale incrémente le compteur de référence sur l&rsquo;objet et l&rsquo;empêche d&rsquo;être nettoyé. Ce résultat n&rsquo;est pas toujours souhaitable, spécifiquement quand une référence circulaire doit être présente ou quand un cache d&rsquo;objet doit être supprimé quand de la mémoire est nécessaire. Une référence faible est une poignée pour un objet qui ne l&rsquo;empêche pas d&rsquo;être nettoyé automatiquement.</p>
<h3 id="références">Références</h3>
<p>Les références faibles d&rsquo;objets sont gérés au-travers de la classe <code>ref</code>. Pour récupérer l&rsquo;objet original, appelez la référence objet.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_ref.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>r <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>ref(obj)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;obj:&#39;</span>, obj)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;ref:&#39;</span>, r)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;r():&#39;</span>, r())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;deleting obj&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;r():&#39;</span>, r())
</span></span></code></pre></div><p>Dans ce cas, puisque <code>obj</code> est supprimé avant le second appel à la référence, la <code>ref</code> retourne <code>None</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_ref.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj: &lt;__main__.ExpensiveObject object at 0x1007b1a58&gt;
</span></span><span style="display:flex;"><span>ref: &lt;weakref at 0x1007a92c8; to <span style="color:#48b685">&#39;ExpensiveObject&#39;</span> at
</span></span><span style="display:flex;"><span>0x1007b1a58&gt;
</span></span><span style="display:flex;"><span>r<span style="color:#5bc4bf">()</span>: &lt;__main__.ExpensiveObject object at 0x1007b1a58&gt;
</span></span><span style="display:flex;"><span>deleting obj
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>Deleting &lt;__main__.ExpensiveObject object at 0x1007b1a58&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>r<span style="color:#5bc4bf">()</span>: None
</span></span></code></pre></div><h3 id="rappels-de-référence">Rappels de Référence</h3>
<p>Le constructeur <code>ref</code> accepte une fonction optionnelle de rappel qui est invoquée quand la référence de l&rsquo;objet est supprimée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_ref_callback.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">callback</span>(reference):
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;&#34;&#34;Invoked when referenced object is deleted&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;callback(</span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(reference))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>r <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>ref(obj, callback)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;obj:&#39;</span>, obj)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;ref:&#39;</span>, r)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;r():&#39;</span>, r())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;deleting obj&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;r():&#39;</span>, r())
</span></span></code></pre></div><p>Le rappel reçoit la référence de l&rsquo;objet en tant qu&rsquo;argument après que la référence soit «morte» et ne se réfère plus à l&rsquo;objet d&rsquo;origine. Une utilisation de cette fonctionnalité est de supprimer la référence faible d&rsquo;un objet depuis un cache.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_ref_callback.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj: &lt;__main__.ExpensiveObject object at 0x1010b1978&gt;
</span></span><span style="display:flex;"><span>ref: &lt;weakref at 0x1010a92c8; to <span style="color:#48b685">&#39;ExpensiveObject&#39;</span> at
</span></span><span style="display:flex;"><span>0x1010b1978&gt;
</span></span><span style="display:flex;"><span>r<span style="color:#5bc4bf">()</span>: &lt;__main__.ExpensiveObject object at 0x1010b1978&gt;
</span></span><span style="display:flex;"><span>deleting obj
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>Deleting &lt;__main__.ExpensiveObject object at 0x1010b1978&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>callback<span style="color:#5bc4bf">(</span>&lt;weakref at 0x1010a92c8; dead&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>r<span style="color:#5bc4bf">()</span>: None
</span></span></code></pre></div><h3 id="finalisation-des-objets">Finalisation des Objets</h3>
<p>Pour une gestion plus robuste des ressources lorsque des références faibles sont nettoyées, utilisez la méthode <code>finalize</code> pour associer les rappels aux objets. Une instance <code>finalize</code> est retenue jusqu&rsquo;à ce que l&rsquo;objet attaché soit supprimé, même si l&rsquo;application ne retient pas de référence à la fin.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_finalize.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_finalize</span>(<span style="color:#5bc4bf">*</span>args):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;on_finalize(</span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(args))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>weakref<span style="color:#5bc4bf">.</span>finalize(obj, on_finalize, <span style="color:#48b685">&#39;extra argument&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span></code></pre></div><p>Les arguments de <code>finalize</code> sont les objets à suivre, un rappel à invoquer quand les objets sont nettoyés, et que les arguments de positions ou nommés sont passés au rappel.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_finalize.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>Deleting &lt;__main__.ExpensiveObject object at 0x1019b10f0&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>on_finalize<span style="color:#5bc4bf">((</span><span style="color:#48b685">&#39;extra argument&#39;</span>,<span style="color:#5bc4bf">))</span>
</span></span></code></pre></div><p>L&rsquo;instance <code>finalize</code> a une propriété en écriture nommée <code>atexit</code> pour contrôler quand le rappel est invoqué lorsqu’un programme se termine, s&rsquo;il n&rsquo;a pas déjà été appelé.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_finalize_atexit.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">sys</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_finalize</span>(<span style="color:#5bc4bf">*</span>args):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;on_finalize(</span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(args))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>f <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>finalize(obj, on_finalize, <span style="color:#48b685">&#39;extra argument&#39;</span>)
</span></span><span style="display:flex;"><span>f<span style="color:#5bc4bf">.</span>atexit <span style="color:#5bc4bf">=</span> bool(int(sys<span style="color:#5bc4bf">.</span>argv[<span style="color:#f99b15">1</span>]))
</span></span></code></pre></div><p>Le comportement par défaut est d&rsquo;invoquer le rappel. Paramétrer <code>atexit</code> sur <code>false</code> désactivera ce comportement.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_finalize_atexit.py <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>on_finalize<span style="color:#5bc4bf">((</span><span style="color:#48b685">&#39;extra argument&#39;</span>,<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>Deleting &lt;__main__.ExpensiveObject object at 0x1007b10f0&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ python3 weakref_finalize_atexit.py <span style="color:#f99b15">0</span>
</span></span></code></pre></div><p>Donner à l&rsquo;instance <code>finalize</code> une référence vers l&rsquo;objet à suivre a pour conséquence de le retenir, ainsi l&rsquo;objet n&rsquo;est jamais passé au ramasse miettes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_finalize_reference.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">gc</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_finalize</span>(<span style="color:#5bc4bf">*</span>args):
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;on_finalize(</span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(args))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>obj_id <span style="color:#5bc4bf">=</span> id(obj)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>f <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>finalize(obj, on_finalize, obj)
</span></span><span style="display:flex;"><span>f<span style="color:#5bc4bf">.</span>atexit <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">False</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> o <span style="color:#5bc4bf">in</span> gc<span style="color:#5bc4bf">.</span>get_objects():
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> id(o) <span style="color:#5bc4bf">==</span> obj_id:
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;found uncollected object in gc&#39;</span>)
</span></span></code></pre></div><p>Comme cet exemple le montre, même si la référence explicite vers <code>obj</code> est supprimée, l&rsquo;objet est retenu et visible par le ramasse miettes au-travers de <code>f</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_finalize_reference.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>found uncollected object in gc
</span></span></code></pre></div><p>Utiliser une méthode liée à un objet suivi en tant rappel peut également empêcher la finalisation correcte de l&rsquo;objet.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_finalize_reference_method.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">gc</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">do_finalize</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;do_finalize&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject()
</span></span><span style="display:flex;"><span>obj_id <span style="color:#5bc4bf">=</span> id(obj)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>f <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>finalize(obj, obj<span style="color:#5bc4bf">.</span>do_finalize)
</span></span><span style="display:flex;"><span>f<span style="color:#5bc4bf">.</span>atexit <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">False</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> o <span style="color:#5bc4bf">in</span> gc<span style="color:#5bc4bf">.</span>get_objects():
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> id(o) <span style="color:#5bc4bf">==</span> obj_id:
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;found uncollected object in gc&#39;</span>)
</span></span></code></pre></div><p>Puisque le rappel donné à <code>finalize</code> est une méthode liée à l&rsquo;instance <code>obj</code>, l&rsquo;objet de finalisation capture une référence  vers <code>obj</code>, qui ne peut être supprimé ou collecté par le ramasse miettes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_finalize_reference_method.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>found uncollected object in gc
</span></span></code></pre></div><h3 id="mandataires">Mandataires</h3>
<p>Il est parfois plus pratique d&rsquo;utiliser un mandataire, plutôt qu&rsquo;une référence faible. Les mandataires peuvent être utilisés comme s&rsquo;il s&rsquo;agissait de l&rsquo;objet d&rsquo;origine et n&rsquo;ont pas besoin d&rsquo;être appelés avant que l&rsquo;objet ne soit accessible. En conséquence, ils peuvent être passés à une bibliothèque qui ne sait pas qu&rsquo;elle reçoit une référence au lieu d&rsquo;un objet réel.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_proxy.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;(Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>obj <span style="color:#5bc4bf">=</span> ExpensiveObject(<span style="color:#48b685">&#39;My Object&#39;</span>)
</span></span><span style="display:flex;"><span>r <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>ref(obj)
</span></span><span style="display:flex;"><span>p <span style="color:#5bc4bf">=</span> weakref<span style="color:#5bc4bf">.</span>proxy(obj)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;via obj:&#39;</span>, obj<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;via ref:&#39;</span>, r()<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;via proxy:&#39;</span>, p<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">del</span> obj
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;via proxy:&#39;</span>, p<span style="color:#5bc4bf">.</span>name)
</span></span></code></pre></div><p>Si le mandataire est accédé après que l&rsquo;objet en référence soit supprimé, une erreur d&rsquo;exception <code>ReferenceError</code> est levée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_proxy.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>via obj: My Object
</span></span><span style="display:flex;"><span>via ref: My Object
</span></span><span style="display:flex;"><span>via proxy: My Object
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>Deleting &lt;__main__.ExpensiveObject object at 0x1007aa7b8&gt;<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Traceback <span style="color:#5bc4bf">(</span>most recent call last<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;weakref_proxy.py&#34;</span>, line 30, in &lt;module&gt;
</span></span><span style="display:flex;"><span>    print<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;via proxy:&#39;</span>, p.name<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>ReferenceError: weakly-referenced object no longer exists
</span></span></code></pre></div><h3 id="mettre-en-cache-des-objets">Mettre en Cache des Objets</h3>
<p>Les classes <code>ref</code> et <code>obj</code> sont considérés de «bas niveau». Bien qu&rsquo;elles soient utiles pour maintenir les références faibles d&rsquo;objets individuels et de permettre des cycles pour être collectés par le ramasse miettes, les classes <code>WeakKeyDictionary</code> et <code>WeakValueDictionary</code> fournissent une API plus appropriée pour créer un cache de plusieurs objets.</p>
<p>La classe <code>WeakValueDictionary</code> utilise les références faibles vers les valeurs qu&rsquo;elle capture, leur permettant d&rsquo;être collectées par le ramasse miettes lorsque tout autre code ne les utilise pas. L&rsquo;utilisation des appels explicites au ramasse miettes illustre la différence entre la gestion de la mémoire avec un dictionnaire standard et <code>WeakValueDictionary</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># weakref_valuedict.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">gc</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">weakref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gc<span style="color:#5bc4bf">.</span>set_debug(gc<span style="color:#5bc4bf">.</span>DEBUG_UNCOLLECTABLE)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">ExpensiveObject</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__repr__</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#48b685">&#39;ExpensiveObject(</span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__del__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;    (Deleting </span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">demo</span>(cache_factory):
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># hold objects so any weak references</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># are not removed immediately</span>
</span></span><span style="display:flex;"><span>    all_refs <span style="color:#5bc4bf">=</span> {}
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># create the cache using the factory</span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;CACHE TYPE:&#39;</span>, cache_factory)
</span></span><span style="display:flex;"><span>    cache <span style="color:#5bc4bf">=</span> cache_factory()
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> name <span style="color:#5bc4bf">in</span> [<span style="color:#48b685">&#39;one&#39;</span>, <span style="color:#48b685">&#39;two&#39;</span>, <span style="color:#48b685">&#39;three&#39;</span>]:
</span></span><span style="display:flex;"><span>        o <span style="color:#5bc4bf">=</span> ExpensiveObject(name)
</span></span><span style="display:flex;"><span>        cache[name] <span style="color:#5bc4bf">=</span> o
</span></span><span style="display:flex;"><span>        all_refs[name] <span style="color:#5bc4bf">=</span> o
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">del</span> o  <span style="color:#776e71"># decref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;  all_refs =&#39;</span>, end<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39; &#39;</span>)
</span></span><span style="display:flex;"><span>    pprint(all_refs)
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">  Before, cache contains:&#39;</span>, list(cache<span style="color:#5bc4bf">.</span>keys()))
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> name, value <span style="color:#5bc4bf">in</span> cache<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;    </span><span style="color:#f99b15">{}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(name, value))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">del</span> value  <span style="color:#776e71"># decref</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># remove all references to the objects except the cache</span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">  Cleanup:&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">del</span> all_refs
</span></span><span style="display:flex;"><span>    gc<span style="color:#5bc4bf">.</span>collect()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">  After, cache contains:&#39;</span>, list(cache<span style="color:#5bc4bf">.</span>keys()))
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> name, value <span style="color:#5bc4bf">in</span> cache<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;    </span><span style="color:#f99b15">{}</span><span style="color:#48b685"> = </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(name, value))
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;  demo returning&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>demo(dict)
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>demo(weakref<span style="color:#5bc4bf">.</span>WeakValueDictionary)
</span></span></code></pre></div><p>Toutes variables de boucle faisant référence aux valeurs mises en cache doivent être explicitement effacées pour que le compte de références de l&rsquo;objet soit décrémenté. Autrement, le ramasse miettes ne supprimera pas les objets, et ils resteront toujours dans le cache. De la même manière, la variable <code>all_refs</code> est utilisée pour capturer les références afin de prévenir que le ramasse miettes les collecte prématurément.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 weakref_valuedict.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>CACHE TYPE: &lt;class <span style="color:#48b685">&#39;dict&#39;</span>&gt;
</span></span><span style="display:flex;"><span>  <span style="color:#ef6155">all_refs</span> <span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;one&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">)</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;three&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">)</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;two&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">)}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  Before, cache contains: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;one&#39;</span>, <span style="color:#48b685">&#39;three&#39;</span>, <span style="color:#48b685">&#39;two&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">one</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">three</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">two</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  Cleanup:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  After, cache contains: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;one&#39;</span>, <span style="color:#48b685">&#39;three&#39;</span>, <span style="color:#48b685">&#39;two&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">one</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">three</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">two</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  demo returning
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>CACHE TYPE: &lt;class <span style="color:#48b685">&#39;weakref.WeakValueDictionary&#39;</span>&gt;
</span></span><span style="display:flex;"><span>  <span style="color:#ef6155">all_refs</span> <span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;one&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">)</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;three&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">)</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;two&#39;</span>: ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">)}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  Before, cache contains: <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;one&#39;</span>, <span style="color:#48b685">&#39;three&#39;</span>, <span style="color:#48b685">&#39;two&#39;</span><span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">one</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">three</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">two</span> <span style="color:#5bc4bf">=</span> ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  Cleanup:
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>one<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>three<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>Deleting ExpensiveObject<span style="color:#5bc4bf">(</span>two<span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  After, cache contains: <span style="color:#5bc4bf">[]</span>
</span></span><span style="display:flex;"><span>  demo returning
</span></span></code></pre></div><p>La classe <code>WeakKeyDictionary</code> fonctionne de manière similaire mais utilise les références faibles pour les clés au lieu des valeurs dans le dictionnaire.</p>
<blockquote>
<p><strong>Attention</strong>
La documentation de la bibliothèque pour <code>weakref</code> contient cet avertissement :
Mise en garde : Étant donné qu&rsquo;un <code>WeakValueDictionary</code> est construit sur un dictionnaire Python, sa taille ne doit pas changer lors de son itération. Cela peut être difficile à garantir pour un <code>WeakValueDictionary</code> parce que les actions effectuées par le programme pendant l&rsquo;itération peuvent entraîner la disparition «par magie» d&rsquo;éléments du dictionnaire (c&rsquo;est un effet de bord du ramasse miettes des collections).</p>
</blockquote>
<h3 id="lire-aussi-10">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/weakref.html" rel="external">Documentation de la bibliothèque standard pour weakref</a></li>
<li><a>gc</a> - le module <code>gc</code> est l&rsquo;interface pour l&rsquo;interprétateur du ramasse miettes.</li>
<li><a href="https://www.python.org/dev/peps/pep-0205" rel="external">PEP 205</a> - Proposition d&rsquo;amélioration des &ldquo;Références Faibles&rdquo;.</li>
</ul>
<h2 id="copy---objets-dupliqués">copy - Objets Dupliqués</h2>
<p><strong>But</strong> : Fournir des fonctions pour dupliquer les objets en utilisant une sémantique de copie superficielle ou profonde</p>
<p>Le module <code>copy</code> inclut deux fonctions, <code>copy()</code> et <code>deepcopy()</code>, pour dupliquer des objets existants.</p>
<h3 id="copies-superficielles">Copies Superficielles</h3>
<p>La <em>copie superficielle</em> créée par <code>copy()</code> est un nouveau conteneur rempli de références vers les contenus de l&rsquo;objet original. Lors de la copie superficielle d&rsquo;un objet <code>list</code>, une nouvelle <code>list</code> est construite et les éléments de l&rsquo;objet original y sont ajoutés.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># copy_shallow.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">copy</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">functools</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">@functools.total_ordering</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">MyClass</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__eq__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">==</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__gt__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">&gt;</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> MyClass(<span style="color:#48b685">&#39;a&#39;</span>)
</span></span><span style="display:flex;"><span>my_list <span style="color:#5bc4bf">=</span> [a]
</span></span><span style="display:flex;"><span>dup <span style="color:#5bc4bf">=</span> copy<span style="color:#5bc4bf">.</span>copy(my_list)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;             my_list:&#39;</span>, my_list)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;                 dup:&#39;</span>, dup)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;      dup is my_list:&#39;</span>, (dup <span style="color:#5bc4bf">is</span> my_list))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;      dup == my_list:&#39;</span>, (dup <span style="color:#5bc4bf">==</span> my_list))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;dup[0] is my_list[0]:&#39;</span>, (dup[<span style="color:#f99b15">0</span>] <span style="color:#5bc4bf">is</span> my_list[<span style="color:#f99b15">0</span>]))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;dup[0] == my_list[0]:&#39;</span>, (dup[<span style="color:#f99b15">0</span>] <span style="color:#5bc4bf">==</span> my_list[<span style="color:#f99b15">0</span>]))
</span></span></code></pre></div><p>Pour une copie superficielle, l&rsquo;instance <code>MyClass</code> n&rsquo;est pas dupliquée, ainsi la référence dans la liste <code>dup</code> est le même objet que celui qui est dans <code>my_list</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 copy_shallow.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>             my_list: <span style="color:#5bc4bf">[</span>&lt;__main__.MyClass object at 0x101f9c160&gt;<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>                 dup: <span style="color:#5bc4bf">[</span>&lt;__main__.MyClass object at 0x101f9c160&gt;<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>      dup is my_list: False
</span></span><span style="display:flex;"><span>      <span style="color:#ef6155">dup</span> <span style="color:#5bc4bf">==</span> my_list: True
</span></span><span style="display:flex;"><span>dup<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span> is my_list<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span>: True
</span></span><span style="display:flex;"><span>dup<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">==</span> my_list<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span>: True
</span></span></code></pre></div><h3 id="copies-profondes">Copies Profondes</h3>
<p>La <em>copie profonde</em> créée par <code>deepcopy()</code> est un nouveau conteneur avec des copies des contenus de l&rsquo;objet original. Pour faire une copie profonde d&rsquo;une <code>list</code>, une nouvelle <code>list</code> est construite, les éléments de la liste originale sont copiés, et ensuite ces copies sont ajoutées à la nouvelle liste.</p>
<p>Remplacer l&rsquo;appel de <code>copy()</code> par <code>deepcopy()</code> fait la différence dans la sortie apparente.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># copy_deep.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">copy</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">functools</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">@functools.total_ordering</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">MyClass</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__eq__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">==</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__gt__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">&gt;</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> MyClass(<span style="color:#48b685">&#39;a&#39;</span>)
</span></span><span style="display:flex;"><span>my_list <span style="color:#5bc4bf">=</span> [a]
</span></span><span style="display:flex;"><span>dup <span style="color:#5bc4bf">=</span> copy<span style="color:#5bc4bf">.</span>deepcopy(my_list)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;             my_list:&#39;</span>, my_list)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;                 dup:&#39;</span>, dup)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;      dup is my_list:&#39;</span>, (dup <span style="color:#5bc4bf">is</span> my_list))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;      dup == my_list:&#39;</span>, (dup <span style="color:#5bc4bf">==</span> my_list))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;dup[0] is my_list[0]:&#39;</span>, (dup[<span style="color:#f99b15">0</span>] <span style="color:#5bc4bf">is</span> my_list[<span style="color:#f99b15">0</span>]))
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;dup[0] == my_list[0]:&#39;</span>, (dup[<span style="color:#f99b15">0</span>] <span style="color:#5bc4bf">==</span> my_list[<span style="color:#f99b15">0</span>]))
</span></span></code></pre></div><p>Le premier élément de la liste n&rsquo;a plus du tout la même référence objet, mais quand les deux objets sont comparés, ils sont toujours évalués comme égaux.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 copy_deep.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>             my_list: <span style="color:#5bc4bf">[</span>&lt;__main__.MyClass object at 0x101e9c160&gt;<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>                 dup: <span style="color:#5bc4bf">[</span>&lt;__main__.MyClass object at 0x1044e1f98&gt;<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>      dup is my_list: False
</span></span><span style="display:flex;"><span>      <span style="color:#ef6155">dup</span> <span style="color:#5bc4bf">==</span> my_list: True
</span></span><span style="display:flex;"><span>dup<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span> is my_list<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span>: False
</span></span><span style="display:flex;"><span>dup<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">==</span> my_list<span style="color:#5bc4bf">[</span>0<span style="color:#5bc4bf">]</span>: True
</span></span></code></pre></div><h3 id="personnaliser-le-comportement-des-copies">Personnaliser le Comportement des Copies</h3>
<p>Il est possible de contrôler comment les copies sont faites en utilisant les méthodes spéciales <code>__copy__()</code> et <code>__deepcopy__()</code>.</p>
<ul>
<li><code>__copy__()</code> est appelée sans aucun argument et devrait retourner une copie superficielle de l&rsquo;objet.</li>
<li><code>__deepcopy__()</code> est appelée avec un dictionnaire memo et devrait retourner une copie profonde de l&rsquo;objet. Tous les attributs membres qui ont besoin d&rsquo;être copiés en profondeur devraient être passé vers <code>copy.deepcopy()</code>, avec le dictionnaire memo, pour contrôler la récursion. (Le dictionnaire memo est expliqué plus tard en détails).</li>
</ul>
<p>L&rsquo;exemple suivant illustre comment les méthodes sont appelées.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># copy_hooks.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">copy</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">functools</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">@functools.total_ordering</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">MyClass</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__eq__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">==</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__gt__</span>(self, other):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">&gt;</span> other<span style="color:#5bc4bf">.</span>name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__copy__</span>(self):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;__copy__()&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> MyClass(self<span style="color:#5bc4bf">.</span>name)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__deepcopy__</span>(self, memo):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;__deepcopy__(</span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(memo))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> MyClass(copy<span style="color:#5bc4bf">.</span>deepcopy(self<span style="color:#5bc4bf">.</span>name, memo))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> MyClass(<span style="color:#48b685">&#39;a&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sc <span style="color:#5bc4bf">=</span> copy<span style="color:#5bc4bf">.</span>copy(a)
</span></span><span style="display:flex;"><span>dc <span style="color:#5bc4bf">=</span> copy<span style="color:#5bc4bf">.</span>deepcopy(a)
</span></span></code></pre></div><p>Le dictionnaire memo est utilisé pour garder la trace des valeurs qui ont été déjà copiées, évitant ainsi une récursion infinie.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 copy_hooks.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>__copy__<span style="color:#5bc4bf">()</span>
</span></span><span style="display:flex;"><span>__deepcopy__<span style="color:#5bc4bf">({})</span>
</span></span></code></pre></div><h3 id="récursion-dans-les-copies-profondes">Récursion dans les Copies Profondes</h3>
<p>Pour éviter les problèmes lors de la duplication récursive des structures de données, <code>deepcopy()</code> utilise un dictionnaire pour suivre les objets qui ont déjà été copiés. Le dictionnaire est passé à la méthode <code>__deepcopy__()</code> afin qu&rsquo;il puisse être examiné là aussi.</p>
<p>Le nouvel exemple montre comment une structure de données interconnectée telle qu&rsquo;un graphe dirigé peut aider à protéger contre la récursivité, en implémentant la méthode <code>__deepcopy__()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># copy_recursion.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">copy</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">Graph</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name, connections):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>connections <span style="color:#5bc4bf">=</span> connections
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">add_connection</span>(self, other):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>connections<span style="color:#5bc4bf">.</span>append(other)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__repr__</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> <span style="color:#48b685">&#39;Graph(name=</span><span style="color:#f99b15">{}</span><span style="color:#48b685">, id=</span><span style="color:#f99b15">{}</span><span style="color:#48b685">)&#39;</span><span style="color:#5bc4bf">.</span>format(
</span></span><span style="display:flex;"><span>            self<span style="color:#5bc4bf">.</span>name, id(self))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__deepcopy__</span>(self, memo):
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">Calling __deepcopy__ for </span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(self))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> self <span style="color:#5bc4bf">in</span> memo:
</span></span><span style="display:flex;"><span>            existing <span style="color:#5bc4bf">=</span> memo<span style="color:#5bc4bf">.</span>get(self)
</span></span><span style="display:flex;"><span>            print(<span style="color:#48b685">&#39;  Already copied to </span><span style="color:#f99b15">{!r}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(existing))
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">return</span> existing
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;  Memo dictionary:&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> memo:
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">for</span> k, v <span style="color:#5bc4bf">in</span> memo<span style="color:#5bc4bf">.</span>items():
</span></span><span style="display:flex;"><span>                print(<span style="color:#48b685">&#39;    </span><span style="color:#f99b15">{}</span><span style="color:#48b685">: </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(k, v))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>            print(<span style="color:#48b685">&#39;    (empty)&#39;</span>)
</span></span><span style="display:flex;"><span>        dup <span style="color:#5bc4bf">=</span> Graph(copy<span style="color:#5bc4bf">.</span>deepcopy(self<span style="color:#5bc4bf">.</span>name, memo), [])
</span></span><span style="display:flex;"><span>        print(<span style="color:#48b685">&#39;  Copying to new object </span><span style="color:#f99b15">{}</span><span style="color:#48b685">&#39;</span><span style="color:#5bc4bf">.</span>format(dup))
</span></span><span style="display:flex;"><span>        memo[self] <span style="color:#5bc4bf">=</span> dup
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> self<span style="color:#5bc4bf">.</span>connections:
</span></span><span style="display:flex;"><span>            dup<span style="color:#5bc4bf">.</span>add_connection(copy<span style="color:#5bc4bf">.</span>deepcopy(c, memo))
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> dup
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>root <span style="color:#5bc4bf">=</span> Graph(<span style="color:#48b685">&#39;root&#39;</span>, [])
</span></span><span style="display:flex;"><span>a <span style="color:#5bc4bf">=</span> Graph(<span style="color:#48b685">&#39;a&#39;</span>, [root])
</span></span><span style="display:flex;"><span>b <span style="color:#5bc4bf">=</span> Graph(<span style="color:#48b685">&#39;b&#39;</span>, [a, root])
</span></span><span style="display:flex;"><span>root<span style="color:#5bc4bf">.</span>add_connection(a)
</span></span><span style="display:flex;"><span>root<span style="color:#5bc4bf">.</span>add_connection(b)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>dup <span style="color:#5bc4bf">=</span> copy<span style="color:#5bc4bf">.</span>deepcopy(root)
</span></span></code></pre></div><p>La classe <code>Graph</code> inclut certaines méthodes basiques de graphe dirigé. Une instance peut être initialisée avec un nom et une liste de nœuds existants auxquels il est connecté. La méthode <code>add_connection()</code> est utilisée pour paramétrer les connexions bidirectionnelles. Elle est aussi utilisée par l&rsquo;opérateur de copie profonde.</p>
<p>La méthode <code>__deepcopy__()</code> imprime les messages pour montrer comment elle est appelée, et gère le contenu du dictionnaire memo selon les besoins. Au lieu de copier en gros la liste complète de connexions, il crée une nouvelle liste et y ajoute des copies des connexions individuelles. Cela permet que le dictionnaire memo soit mise à jour à chaque fois qu&rsquo;un nouveau nœud est dupliqué, et évite les problèmes de récursion ou de copies supplémentaires de nœuds. Comme précédemment, la méthode retourne la copie d&rsquo;objet quand il est fait.</p>
<p>
                <figure role="figure" aria-label="Copie profonde d’un graphe objet avec des cycles">
    <a href="/images/dvp.net/graphviz.png" title="Copie profonde d’un graphe objet avec des cycles">
        <picture>
            <source srcset="/images/dvp.net/graphviz.png.avif" type="image/avif"><source srcset="/images/dvp.net/graphviz_hu_e477dab336ee22d2.webp" type="image/webp">
            <img alt="Copie profonde d’un graphe objet avec des cycles" height="251" id="img_images_dvp.net_graphviz.png_0" loading="lazy" src="/images/dvp.net/graphviz.png" type="image/png" width="168">
        </picture>
    </a>
    <figcaption>Copie profonde d’un graphe objet avec des cycles</figcaption>
</figure></p>
<p>Le graphe vu dans la figure inclut les nombreux cycles, mais la gestion de la récursion avec le dictionnaire memo empêche la traversée de provoquer une erreur de débordement de pile. Quand le nœud <em>root</em> est copié, il produit la sortie suivante.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 copy_recursion.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Calling __deepcopy__ <span style="color:#815ba4">for</span> Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183824<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Memo dictionary:
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>empty<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Copying to new object Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367233208<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Calling __deepcopy__ <span style="color:#815ba4">for</span> Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326186344<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Memo dictionary:
</span></span><span style="display:flex;"><span>    Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183824<span style="color:#5bc4bf">)</span>: Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367233208<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Copying to new object Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367234720<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Calling __deepcopy__ <span style="color:#815ba4">for</span> Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183824<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Already copied to Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367233208<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Calling __deepcopy__ <span style="color:#815ba4">for</span> Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>b, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183880<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Memo dictionary:
</span></span><span style="display:flex;"><span>    Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183824<span style="color:#5bc4bf">)</span>: Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367233208<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326186344<span style="color:#5bc4bf">)</span>: Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367234720<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    4326183824: Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367233208<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    4367217936: <span style="color:#5bc4bf">[</span>Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>root, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326183824<span style="color:#5bc4bf">)</span>, Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4326186344<span style="color:#5bc4bf">)]</span>
</span></span><span style="display:flex;"><span>    4326186344: Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>a, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367234720<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  Copying to new object Graph<span style="color:#5bc4bf">(</span><span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>b, <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4367235000<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>La seconde fois où le nœud <em>root</em> est rencontré, pendant que le nœud <em>a</em> soit copié, <code>__deepcopy__()</code> détecte la récursion et réutilise la valeur existante du dictionnaire memo au lieu de créer un nouvel objet.</p>
<h3 id="lire-aussi-11">Lire aussi</h3>
<ul>
<li><a href="https://docs.python.org/fr/3.7/library/copy.html" rel="external">Documentation de la bibliothèque standard pour copy</a></li>
</ul>
<h2 id="pprint---structures-de-données-pretty-print">pprint - Structures de Données Pretty-Print</h2>
<p><strong>But</strong> : Structures de données Pretty-print</p>
<p>Le module <code>pprint</code> contient une «jolie imprimante» pour produire des vues esthétiques des structures de données. Le formateur produit des représentations de structures de données qui peuvent être analysées correctement par l&rsquo;interpréteur, et qui sont aussi faciles à lire pour un humain. La sortie est conservée sur une seule ligne, si possible, et en retrait lorsqu&rsquo;elle est fractionnée sur plusieurs lignes.</p>
<p>Les exemples dans ce chapitre dépendent tous du script <code>pprint_data.py</code>, qui est montré ici.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_data.py</span>
</span></span><span style="display:flex;"><span>data <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>    (<span style="color:#f99b15">1</span>, {<span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span>}),
</span></span><span style="display:flex;"><span>    (<span style="color:#f99b15">2</span>, {<span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>, <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>         <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>, <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>, <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>, <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span>}),
</span></span><span style="display:flex;"><span>    (<span style="color:#f99b15">3</span>, [<span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span>]),
</span></span><span style="display:flex;"><span>    (<span style="color:#f99b15">4</span>, [<span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span>]),
</span></span><span style="display:flex;"><span>    (<span style="color:#f99b15">5</span>, [<span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;t&#39;&#39;u&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span>]),
</span></span><span style="display:flex;"><span>]
</span></span></code></pre></div><h3 id="impression">Impression</h3>
<p>La manière la plus simple d&rsquo;utiliser le module est au-travers de la fonction <code>pprint()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_pprint.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint_data</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;PRINT:&#39;</span>)
</span></span><span style="display:flex;"><span>print(data)
</span></span><span style="display:flex;"><span>print()
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;PPRINT:&#39;</span>)
</span></span><span style="display:flex;"><span>pprint(data)
</span></span></code></pre></div><p><code>pprint()</code> formate un objet et l&rsquo;écrit dans le flux de données en le passant en argument (ou <code>sys.stdout</code> par défaut).</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_pprint.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>PRINT:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>, <span style="color:#5bc4bf">(</span>2, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;f&#39;</span>:
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;F&#39;</span>, <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>, <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>, <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>, <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>, <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>, <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>, <span style="color:#5bc4bf">(</span>
</span></span><span style="display:flex;"><span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>, <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>, <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>PPRINT:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span></code></pre></div><h3 id="formatage">Formatage</h3>
<p>Pour formater une structure de données sans l&rsquo;écrire directement vers un flux (par exemple, pour la journalisation) utilisez <code>pformat()</code> pour construire une représentation de chaînes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_pformat.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">logging</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pformat
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint_data</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>logging<span style="color:#5bc4bf">.</span>basicConfig(
</span></span><span style="display:flex;"><span>    level<span style="color:#5bc4bf">=</span>logging<span style="color:#5bc4bf">.</span>DEBUG,
</span></span><span style="display:flex;"><span>    format<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;</span><span style="color:#f99b15">%(levelname)-8s</span><span style="color:#48b685"> </span><span style="color:#f99b15">%(message)s</span><span style="color:#48b685">&#39;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>logging<span style="color:#5bc4bf">.</span>debug(<span style="color:#48b685">&#39;Logging pformatted data&#39;</span>)
</span></span><span style="display:flex;"><span>formatted <span style="color:#5bc4bf">=</span> pformat(data)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> line <span style="color:#5bc4bf">in</span> formatted<span style="color:#5bc4bf">.</span>splitlines():
</span></span><span style="display:flex;"><span>    logging<span style="color:#5bc4bf">.</span>debug(line<span style="color:#5bc4bf">.</span>rstrip())
</span></span></code></pre></div><p>La chaîne formatée peut alors être imprimée ou journalisée indépendamment.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_pformat.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DEBUG    Logging pformatted data
</span></span><span style="display:flex;"><span>DEBUG    <span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span>DEBUG     <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>DEBUG      <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>DEBUG       <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span>DEBUG     <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span>DEBUG     <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span>DEBUG     <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span></code></pre></div><h3 id="classes-arbitraires">Classes Arbitraires</h3>
<p>La classe <code>PrettyPrinter</code> utilisée par <code>pprint()</code> peut aussi fonctionner avec des classes personnalisées, si elles définissent une méthode <code>__repr__()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_arbitrary_object.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">node</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self, name, contents<span style="color:#5bc4bf">=</span>[]):
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>name <span style="color:#5bc4bf">=</span> name
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>contents <span style="color:#5bc4bf">=</span> contents[:]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__repr__</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">return</span> (
</span></span><span style="display:flex;"><span>            <span style="color:#48b685">&#39;node(&#39;</span> <span style="color:#5bc4bf">+</span> repr(self<span style="color:#5bc4bf">.</span>name) <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;, &#39;</span> <span style="color:#5bc4bf">+</span>
</span></span><span style="display:flex;"><span>            repr(self<span style="color:#5bc4bf">.</span>contents) <span style="color:#5bc4bf">+</span> <span style="color:#48b685">&#39;)&#39;</span>
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>trees <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>    node(<span style="color:#48b685">&#39;node-1&#39;</span>),
</span></span><span style="display:flex;"><span>    node(<span style="color:#48b685">&#39;node-2&#39;</span>, [node(<span style="color:#48b685">&#39;node-2-1&#39;</span>)]),
</span></span><span style="display:flex;"><span>    node(<span style="color:#48b685">&#39;node-3&#39;</span>, [node(<span style="color:#48b685">&#39;node-3-1&#39;</span>)]),
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span>pprint(trees)
</span></span></code></pre></div><p>Les représentations de ces objets imbriqués sont combinées par <code>PrettyPrinter</code> pour retourner une représentation complète de chaînes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_arbitrary_object.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>node<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;node-1&#39;</span>, <span style="color:#5bc4bf">[])</span>,
</span></span><span style="display:flex;"><span> node<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;node-2&#39;</span>, <span style="color:#5bc4bf">[</span>node<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;node-2-1&#39;</span>, <span style="color:#5bc4bf">[])])</span>,
</span></span><span style="display:flex;"><span> node<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;node-3&#39;</span>, <span style="color:#5bc4bf">[</span>node<span style="color:#5bc4bf">(</span><span style="color:#48b685">&#39;node-3-1&#39;</span>, <span style="color:#5bc4bf">[])])]</span>
</span></span></code></pre></div><h3 id="récursion">Récursion</h3>
<p>Les structures de données récursives sont représentées avec une référence vers la source originale de données, restituées dans le format <code>&lt;Recursion on typename with id=number&gt;</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_recursion.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>local_data <span style="color:#5bc4bf">=</span> [<span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, <span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>]
</span></span><span style="display:flex;"><span>local_data<span style="color:#5bc4bf">.</span>append(local_data)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;id(local_data) =&gt;&#39;</span>, id(local_data))
</span></span><span style="display:flex;"><span>pprint(local_data)
</span></span></code></pre></div><p>Dans cet exemple, la liste <code>local_data</code> est ajoutée à elle-même, créant une référence récursive.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_recursion.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>id<span style="color:#5bc4bf">(</span>local_data<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">=</span>&gt; <span style="color:#f99b15">4358913288</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;a&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>, 1, 2, &lt;Recursion on list with <span style="color:#ef6155">id</span><span style="color:#5bc4bf">=</span>4358913288&gt;<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><h3 id="limiter-la-sortie-imbriquée">Limiter la Sortie Imbriquée</h3>
<p>Pour des structures de données très profondes, il peut ne pas être désirable que la sortie inclut tous les détails. La donnée peut ne pas être formatée proprement, le texte formaté est peut-être trop volumineux pour être géré, ou certaines données peuvent être superflues.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_depth.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint_data</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pprint(data, depth<span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>)
</span></span><span style="display:flex;"><span>pprint(data, depth<span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span>)
</span></span></code></pre></div><p>Utilisez l&rsquo;argument <code>depth</code> pour contrôler jusqu&rsquo;où dans la structure de données imbriquée l&rsquo;imprimante peut faire une récursion. Les niveaux non inclus dans la sortie sont représentés par une ellipse.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_depth.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>...<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>, <span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)]</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span>...<span style="color:#5bc4bf">})</span>, <span style="color:#5bc4bf">(</span>2, <span style="color:#5bc4bf">{</span>...<span style="color:#5bc4bf">})</span>, <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span>...<span style="color:#5bc4bf">])</span>, <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span>...<span style="color:#5bc4bf">])</span>, <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span>...<span style="color:#5bc4bf">])]</span>
</span></span></code></pre></div><h3 id="contrôler-la-largeur-de-la-sortie">Contrôler la Largeur de la Sortie</h3>
<p>La sortie par défaut pour le texte formaté est de 80 colonnes. Pour ajuster la largeur, utilisez l&rsquo;argument <code>width</code> de <code>pprint()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_width.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint_data</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> width <span style="color:#5bc4bf">in</span> [<span style="color:#f99b15">80</span>, <span style="color:#f99b15">5</span>]:
</span></span><span style="display:flex;"><span>    print(<span style="color:#48b685">&#39;WIDTH =&#39;</span>, width)
</span></span><span style="display:flex;"><span>    pprint(data, width<span style="color:#5bc4bf">=</span>width)
</span></span><span style="display:flex;"><span>    print()
</span></span></code></pre></div><p>Quand la largeur est trop petite pour accommoder la structure de données formatée, les lignes ne sont pas tronquées, ni encapsulées au cas où cela introduirait une syntaxe non valide.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_width.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">WIDTH</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">80</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">WIDTH</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>3,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>4,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;p&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>5,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;s&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;tu&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;v&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;x&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;y&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span></code></pre></div><p>Le drapeau <code>compact</code> demande à <code>pprint()</code> d&rsquo;essayer de mettre plus de données sur chaque ligne individuelle, plutôt que d&rsquo;étendre des structures de données complexes sur plusieurs lignes.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#776e71"># pprint_compact.py</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint</span> <span style="color:#5bc4bf">import</span> pprint
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">pprint_data</span> <span style="color:#5bc4bf">import</span> data
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;DEFAULT:&#39;</span>)
</span></span><span style="display:flex;"><span>pprint(data, compact<span style="color:#5bc4bf">=</span><span style="color:#815ba4">False</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#48b685">&#39;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">COMPACT:&#39;</span>)
</span></span><span style="display:flex;"><span>pprint(data, compact<span style="color:#5bc4bf">=</span><span style="color:#815ba4">True</span>)
</span></span></code></pre></div><p>Cet exemple montre que quand une structure de données ne tient pas sur une ligne, elle est scindée (comme pour le deuxième élément de la liste de données). Quand de multiples éléments peuvent tenir sur une ligne, comme avec le troisième ou quatrième membre, ils sont placés de cette façon.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ python3 pprint_compact.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DEFAULT:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>COMPACT:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[(</span>1, <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;a&#39;</span>: <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;b&#39;</span>: <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;c&#39;</span>: <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;d&#39;</span>: <span style="color:#48b685">&#39;D&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>2,
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">{</span><span style="color:#48b685">&#39;e&#39;</span>: <span style="color:#48b685">&#39;E&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;f&#39;</span>: <span style="color:#48b685">&#39;F&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;g&#39;</span>: <span style="color:#48b685">&#39;G&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;h&#39;</span>: <span style="color:#48b685">&#39;H&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;i&#39;</span>: <span style="color:#48b685">&#39;I&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;j&#39;</span>: <span style="color:#48b685">&#39;J&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;k&#39;</span>: <span style="color:#48b685">&#39;K&#39;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#48b685">&#39;l&#39;</span>: <span style="color:#48b685">&#39;L&#39;</span><span style="color:#5bc4bf">})</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>3, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;m&#39;</span>, <span style="color:#48b685">&#39;n&#39;</span><span style="color:#5bc4bf">])</span>, <span style="color:#5bc4bf">(</span>4, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;o&#39;</span>, <span style="color:#48b685">&#39;p&#39;</span>, <span style="color:#48b685">&#39;q&#39;</span><span style="color:#5bc4bf">])</span>,
</span></span><span style="display:flex;"><span> <span style="color:#5bc4bf">(</span>5, <span style="color:#5bc4bf">[</span><span style="color:#48b685">&#39;r&#39;</span>, <span style="color:#48b685">&#39;s&#39;</span>, <span style="color:#48b685">&#39;tu&#39;</span>, <span style="color:#48b685">&#39;v&#39;</span>, <span style="color:#48b685">&#39;x&#39;</span>, <span style="color:#48b685">&#39;y&#39;</span>, <span style="color:#48b685">&#39;z&#39;</span><span style="color:#5bc4bf">])]</span>
</span></span></code></pre></div><ul>
<li>[API]: Application Programming Interface - Interface de Programmation Applicative</li>
<li>[PEP]: Python Enhancement Proposals - Propositions d&rsquo;Amélioration Python</li>
<li>[RSS]: Really Simple Syndication - Syndication de contenu réellement simple</li>
<li>[URL]: Uniform Resource Locator - Repère uniforme de ressource</li>
<li>[p.ex.]: par exemple</li>
</ul>
]]></content>
        <summary type="html"><![CDATA[Relecture du chapitre 2 - Python 3 Module of the Week pour la communauté DVP]]></summary>
        <published>2019-05-16T21:31:01+01:00</published>
        <updated>2019-06-11T14:12:01+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:18061967-797d-6b5d-16cd-f5ddc444b104</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/developpez.net/dive-into-python-8-iterateurs-avances/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Dive Into Python 3 - 8 : Itérateurs avancés</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Python" scheme="http://doc.huc.fr.eu.org/fr/tags/python/" />
        <content type="html"><![CDATA[<h1 id="dive-into-python-3---8--itérateurs-avancés">Dive Into Python 3 - 8 : Itérateurs avancés</h1>
<blockquote>
<p>Great fleas have little fleas upon their backs to bite ’em, And little fleas have lesser fleas, and so ad infinitum. — Augustus De Morgan</p>
</blockquote>
<h2 id="en-plongée">En plongée</h2>
<p>Tout comme les <a>expressions régulières</a> dopent les <a>chaînes</a> aux stéroïdes, le module <code>itertools</code> dopent les <a>itérateurs</a> aux stéroïdes. Mais d&rsquo;abord, je veux vous montrer un puzzle classique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>HAWAII <span style="color:#5bc4bf">+</span> IDAHO <span style="color:#5bc4bf">+</span> IOWA <span style="color:#5bc4bf">+</span> OHIO <span style="color:#5bc4bf">==</span> STATES
</span></span><span style="display:flex;"><span><span style="color:#f99b15">510199</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">98153</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">9301</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">3593</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">621246</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>H <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span>A <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>W <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>I <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>D <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">8</span>
</span></span><span style="display:flex;"><span>O <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>S <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">6</span>
</span></span><span style="display:flex;"><span>T <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>E <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4</span>
</span></span></code></pre></div><p>De tels puzzles sont appelés <em>cryptarithmes</em> ou <em>alphamétiques</em>. Les lettres épellent des mots réels, mais si vous remplacez chaque lettre par un chiffre de <code>0-9</code>, elles « épellent » aussi une équation arithmétique. L&rsquo;astuce consiste à déterminer quelle lettre correspond à chaque chiffre. Toutes les occurrences de chaque lettre doivent correspondre au même chiffre, aucun chiffre ne doit être répété, et aucun « mot » ne peut démarrer avec le chiffre 0.</p>
<p>Dans ce chapitre, nous plongerons en profondeur dans un incroyable programme Python écrit à l’origine par Raymond Hettinger. Ce programme résout les puzzles alphamétiques en seulement <em>14 lignes de code</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">itertools</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">solve</span>(puzzle):
</span></span><span style="display:flex;"><span>    words <span style="color:#5bc4bf">=</span> re<span style="color:#5bc4bf">.</span>findall(<span style="color:#48b685">&#39;[A-Z]+&#39;</span>, puzzle<span style="color:#5bc4bf">.</span>upper())
</span></span><span style="display:flex;"><span>    unique_characters <span style="color:#5bc4bf">=</span> set(<span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(words))
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">assert</span> len(unique_characters) <span style="color:#5bc4bf">&lt;=</span> <span style="color:#f99b15">10</span>, <span style="color:#48b685">&#39;Too many letters&#39;</span>
</span></span><span style="display:flex;"><span>    first_letters <span style="color:#5bc4bf">=</span> {word[<span style="color:#f99b15">0</span>] <span style="color:#815ba4">for</span> word <span style="color:#5bc4bf">in</span> words}
</span></span><span style="display:flex;"><span>    n <span style="color:#5bc4bf">=</span> len(first_letters)
</span></span><span style="display:flex;"><span>    sorted_characters <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(first_letters) <span style="color:#5bc4bf">+</span> \
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(unique_characters <span style="color:#5bc4bf">-</span> first_letters)
</span></span><span style="display:flex;"><span>    characters <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> sorted_characters)
</span></span><span style="display:flex;"><span>    digits <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> <span style="color:#48b685">&#39;0123456789&#39;</span>)
</span></span><span style="display:flex;"><span>    zero <span style="color:#5bc4bf">=</span> digits[<span style="color:#f99b15">0</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> guess <span style="color:#5bc4bf">in</span> itertools<span style="color:#5bc4bf">.</span>permutations(digits, len(characters)):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> zero <span style="color:#5bc4bf">not</span> <span style="color:#5bc4bf">in</span> guess[:n]:
</span></span><span style="display:flex;"><span>            equation <span style="color:#5bc4bf">=</span> puzzle<span style="color:#5bc4bf">.</span>translate(dict(zip(characters, guess)))
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">if</span> eval(equation):
</span></span><span style="display:flex;"><span>                <span style="color:#815ba4">return</span> equation
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#ef6155">__name__</span> <span style="color:#5bc4bf">==</span> <span style="color:#48b685">&#39;__main__&#39;</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">import</span> <span style="color:#fec418">sys</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> puzzle <span style="color:#5bc4bf">in</span> sys<span style="color:#5bc4bf">.</span>argv[<span style="color:#f99b15">1</span>:]:
</span></span><span style="display:flex;"><span>        print(puzzle)
</span></span><span style="display:flex;"><span>        solution <span style="color:#5bc4bf">=</span> solve(puzzle)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> solution:
</span></span><span style="display:flex;"><span>            print(solution)
</span></span></code></pre></div><p>Vous pouvez exécuter ce programme depuis la ligne de commande. Sous Linux, cela ressemblerait à ceci. (Cela peut prendre un peu de temps, selon la vitesse de votre ordinateur, et comme il n’y a pas de barre de progression, soyez patient !)</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>you@localhost:~/diveintopython3/examples$ python3 alphametics.py <span style="color:#48b685">&#34;HAWAII + IDAHO + IOWA + OHIO == STATES&#34;</span>
</span></span><span style="display:flex;"><span>HAWAII + IDAHO + IOWA + <span style="color:#ef6155">OHIO</span> <span style="color:#5bc4bf">=</span> STATES
</span></span><span style="display:flex;"><span><span style="color:#f99b15">510199</span> + <span style="color:#f99b15">98153</span> + <span style="color:#f99b15">9301</span> + <span style="color:#ef6155">3593</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">621246</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>you@localhost:~/diveintopython3/examples$ python3 alphametics.py <span style="color:#48b685">&#34;I + LOVE + YOU == DORA&#34;</span>
</span></span><span style="display:flex;"><span>I + LOVE + <span style="color:#ef6155">YOU</span> <span style="color:#5bc4bf">==</span> DORA
</span></span><span style="display:flex;"><span><span style="color:#f99b15">1</span> + <span style="color:#f99b15">2784</span> + <span style="color:#ef6155">975</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">3760</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>you@localhost:~/diveintopython3/examples$ python3 alphametics.py <span style="color:#48b685">&#34;SEND + MORE == MONEY&#34;</span>
</span></span><span style="display:flex;"><span>SEND + <span style="color:#ef6155">MORE</span> <span style="color:#5bc4bf">==</span> MONEY
</span></span><span style="display:flex;"><span><span style="color:#f99b15">9567</span> + <span style="color:#ef6155">1085</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">10652</span>
</span></span></code></pre></div><h2 id="trouver-toutes-les-occurrences-dun-motif">Trouver toutes les occurrences d’un motif</h2>
<p>La première chose que ce résolveur alphamétique fait est de trouver toutes les lettres (A-Z) dans le puzzle.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">re</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>findall(<span style="color:#48b685">&#39;[0-9]+&#39;</span>, <span style="color:#48b685">&#39;16 2-by-4s in rows of 8&#39;</span>)  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;16&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>, <span style="color:#48b685">&#39;4&#39;</span>, <span style="color:#48b685">&#39;8&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>findall(<span style="color:#48b685">&#39;[A-Z]+&#39;</span>, <span style="color:#48b685">&#39;SEND + MORE == MONEY&#39;</span>)     <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;SEND&#39;</span>, <span style="color:#48b685">&#39;MORE&#39;</span>, <span style="color:#48b685">&#39;MONEY&#39;</span>]
</span></span></code></pre></div><p>① Le module <code>re</code> est une implémentation Python des <a>expressions régulières</a>. Il a une fonction astucieuse appelée <code>findall()</code> qui prend un motif d&rsquo;expression régulière et une chaîne, et trouve toutes les occurrences du motif dans la chaîne. Dans ce cas, le motif correspond aux séquences de nombres. La fonction <code>findall()</code> retourne une liste de toutes les sous-chaînes qui  correspondent au motif.</p>
<p>② Ici est le motif d&rsquo;expression régulière qui correspond aux séquences de lettres. Une fois encore, la valeur de retour est une liste, et chaque item dans la liste est une chaîne qui correspond au motif d’expression régulière.</p>
<p>Voici un autre exemple qui stimulera un peu votre cerveau.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> re<span style="color:#5bc4bf">.</span>findall(<span style="color:#48b685">&#39; s.*? s&#39;</span>, <span style="color:#48b685">&#34;The sixth sick sheikh&#39;s sixth sheep&#39;s sick.&#34;</span>)
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39; sixth s&#39;</span>, <span style="color:#48b685">&#34; sheikh&#39;s s&#34;</span>, <span style="color:#48b685">&#34; sheep&#39;s s&#34;</span>]
</span></span></code></pre></div><p>Surpris ?
L’expression régulière recherche un espace, un <code>s</code>, et ensuite la plus petite série possible de tout caractère <code>(.*?)</code>, suivi d’un espace et encore d’un <code>s</code>. Bien, en regardant cette chaîne en entrée, je vois cinq correspondances :</p>
<ol>
<li>The<code> sixth s</code>ick sheikh&rsquo;s sixth sheep&rsquo;s sick.</li>
<li>The sixth<code> sick s</code>heikh&rsquo;s sixth sheep&rsquo;s sick.</li>
<li>The sixth sick<code> sheikh's s</code>ixth sheep&rsquo;s sick.</li>
<li>The sixth sick sheikh&rsquo;s<code> sixth s</code>heep&rsquo;s sick.</li>
<li>The sixth sick sheikh&rsquo;s sixth<code> sheep's s</code>ick.</li>
</ol>
<p>Mais la fonction <code>re.findall()</code> ne retourne seulement que trois correspondances. Elle retourne spécifiquement la première, la troisième et la cinquième. Pourquoi cela ?
Parce qu’ <em>elle ne renvoie pas les correspondances qui se chevauchent</em>. La première correspondance chevauche la seconde, ainsi la première est retournée et la seconde est sautée. Ensuite, la troisième chevauche la quatrième, ainsi la troisième est retournée et la quatrième est sautée. Finalement, la cinquième est retournée. Trois correspondances et pas cinq.</p>
<p>Cela n&rsquo;a rien à voir avec le résolveur alphamétique ; Je pensais juste que c&rsquo;était intéressant.</p>
<h2 id="trouver-les-items-uniques-dans-une-séquence">Trouver les items uniques dans une séquence</h2>
<p><a>Sets</a> rend trivial la recherche d’items uniques dans une séquence.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> a_list <span style="color:#5bc4bf">=</span> [<span style="color:#48b685">&#39;The&#39;</span>, <span style="color:#48b685">&#39;sixth&#39;</span>, <span style="color:#48b685">&#39;sick&#39;</span>, <span style="color:#48b685">&#34;sheik&#39;s&#34;</span>, <span style="color:#48b685">&#39;sixth&#39;</span>, <span style="color:#48b685">&#34;sheep&#39;s&#34;</span>, <span style="color:#48b685">&#39;sick&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> set(a_list)                      <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>{<span style="color:#48b685">&#39;sixth&#39;</span>, <span style="color:#48b685">&#39;The&#39;</span>, <span style="color:#48b685">&#34;sheep&#39;s&#34;</span>, <span style="color:#48b685">&#39;sick&#39;</span>, <span style="color:#48b685">&#34;sheik&#39;s&#34;</span>}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> a_string <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;EAST IS EAST&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> set(a_string)                    <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>{<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39; &#39;</span>, <span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;I&#39;</span>, <span style="color:#48b685">&#39;S&#39;</span>, <span style="color:#48b685">&#39;T&#39;</span>}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> words <span style="color:#5bc4bf">=</span> [<span style="color:#48b685">&#39;SEND&#39;</span>, <span style="color:#48b685">&#39;MORE&#39;</span>, <span style="color:#48b685">&#39;MONEY&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(words)                   <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;SENDMOREMONEY&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> set(<span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(words))              <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span>{<span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;D&#39;</span>, <span style="color:#48b685">&#39;M&#39;</span>, <span style="color:#48b685">&#39;O&#39;</span>, <span style="color:#48b685">&#39;N&#39;</span>, <span style="color:#48b685">&#39;S&#39;</span>, <span style="color:#48b685">&#39;R&#39;</span>, <span style="color:#48b685">&#39;Y&#39;</span>}
</span></span></code></pre></div><p>① À une liste donnée de nombreuses chaînes, la fonction <code>set()</code> retournera un ensemble de chaînes uniques depuis la liste. Cela à du sens si vous le considérez comme une boucle <code>for</code>. Prendre le premier item de la liste, et le mettre dans l’ensemble. Le second. Le troisième. Le quatrième. Le cinquième - attendez, c’est déjà dans l’ensemble, donc il n’est répertorié qu’une fois, car les ensembles Python n’autorisent pas les doublons. La sixième. La septième – encore, une dupliquée, qui ne sera listée qu’une fois. Le résultat final ? Chacun des items uniques de la liste originale, sans duplication. La liste originale n&rsquo;a même pas besoin d&rsquo;être triée en premier.</p>
<p>② La même technique fonctionne avec les chaînes, puisqu’une chaîne est une séquence de caractères.</p>
<p>③ À une liste donnée de chaînes, <code>''.join(a_list)</code> concatène toutes les chaînes ensemble en une seule.</p>
<p>④ Ainsi, à une liste donnée de chaînes, la ligne de code retourne tous les caractères uniques dans toutes les chaînes, sans duplication.</p>
<p>Le résolveur alphamétique utilise cette technique pour construire un ensemble de tous les caractères uniques dans le puzzle.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>unique_characters <span style="color:#5bc4bf">=</span> set(<span style="color:#48b685">&#39;&#39;</span><span style="color:#5bc4bf">.</span>join(words))
</span></span></code></pre></div><p>Cette liste est utilisée plus tard pour assigner des chiffres aux caractères ainsi le résolveur parcourt les solutions possibles.</p>
<h2 id="créer-des-assertions">Créer des assertions</h2>
<p>Tout comme beaucoup de langages de programmation, Python a une instruction <code>assert</code>. Voici  comment elle fonctionne :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">assert</span> <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">2</span>                                     <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">assert</span> <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">3</span>                                     <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">AssertionError</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">assert</span> <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">+</span> <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">5</span>, <span style="color:#48b685">&#34;Only for very large values of 2&#34;</span>  <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">AssertionError</span>: Only <span style="color:#815ba4">for</span> very large values of <span style="color:#f99b15">2</span>
</span></span></code></pre></div><p>① L’instruction <code>assert</code> est suivie de toute expression Python valide. Dans ce cas, l’expression <code>1 + 1 == 2</code> est évaluée à <code>True</code>, l’instruction <code>assert</code> ne fait rien.</p>
<p>② Toutefois, si l’expression Python est évaluée à <code>False</code>, l’instruction <code>assert</code> lèvera une <code>AssertionError</code>.</p>
<p>③ Vous pouvez aussi inclure un message humainement compréhensible qui est affiché si <code>AssertionError</code> est levée.</p>
<p>Donc, cette ligne de code :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">assert</span> len(unique_characters) <span style="color:#5bc4bf">&lt;=</span> <span style="color:#f99b15">10</span>, <span style="color:#48b685">&#39;Too many letters&#39;</span>
</span></span></code></pre></div><p>… est équivalente à cela :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">if</span> len(unique_characters) <span style="color:#5bc4bf">&gt;</span> <span style="color:#f99b15">10</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">raise</span> <span style="color:#ef6155">AssertionError</span>(<span style="color:#48b685">&#39;Too many letters&#39;</span>)
</span></span></code></pre></div><p>Le résolveur alphamétique utilise l’instruction exacte <code>assert</code> pour s&rsquo;affranchir rapidement si le puzzle contient plus de dix lettres uniques. Puisque chaque lettre est assignée à un chiffre unique, et qu’il y a seulement dix chiffres, un puzzle avec plus de dix lettres uniques ne peut pas avoir de solution possible.</p>
<h2 id="générateur-dexpressions">Générateur d’expressions</h2>
<p>Un générateur d’expression est tout comme un <a>générateur de fonction</a> mais sans fonction.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> unique_characters <span style="color:#5bc4bf">=</span> {<span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;D&#39;</span>, <span style="color:#48b685">&#39;M&#39;</span>, <span style="color:#48b685">&#39;O&#39;</span>, <span style="color:#48b685">&#39;N&#39;</span>, <span style="color:#48b685">&#39;S&#39;</span>, <span style="color:#48b685">&#39;R&#39;</span>, <span style="color:#48b685">&#39;Y&#39;</span>}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> gen <span style="color:#5bc4bf">=</span> (ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> unique_characters)  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> gen                                        <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span>generator object <span style="color:#5bc4bf">&lt;</span>genexpr<span style="color:#5bc4bf">&gt;</span> at <span style="color:#f99b15">0x00BADC10</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(gen)                                  <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">69</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(gen)
</span></span><span style="display:flex;"><span><span style="color:#f99b15">68</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> unique_characters)   <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">69</span>, <span style="color:#f99b15">68</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">79</span>, <span style="color:#f99b15">78</span>, <span style="color:#f99b15">83</span>, <span style="color:#f99b15">82</span>, <span style="color:#f99b15">89</span>)
</span></span></code></pre></div><p>① Un générateur d’expression est comme une fonction anonyme qui donne des valeurs. L’expression ressemble en elle-même à une <a>liste de compréhension</a>, mais elle est entourée de parenthèses au lieu de crochets.</p>
<p>② Le générateur d’expression retourne… un itérateur.</p>
<p>③ L’appel à <code>next(gen)</code> retourne la valeur suivante dans l’itérateur.</p>
<p>④ Si vous le souhaitez, vous pouvez itérer au-travers toutes les valeurs possibles et retourner un tuple, une liste, ou un ensemble, en soumettant le générateur d’expression à <code>tuple()</code>, <code>list()</code> ou <code>set()</code>. Dans ces cas, vous n’avez pas besoin de parenthèses supplémentaires – il suffit de passer l’expression <code>ord(c) for c in unique_characters</code> telle qu’elle à la fonction <code>tuple()</code>, et Python comprend que c’est un générateur d’expressions.</p>
<p><strong>Utiliser un générateur d’expressions au lieu d’une liste de compréhension peut soulager à la fois le CPU et la RAM. Si vous construisez une liste pour juste la détruire ensuite (p. ex. pour la passer à <code>tuple()</code> ou <code>set()</code>), utilisez plutôt un générateur d’expression.</strong></p>
<p>Voici une autre manière d’accomplir la même chose, en utilisant un <a>générateur de fonction</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">ord_map</span>(a_string):
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> a_string:
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">yield</span> ord(c)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gen <span style="color:#5bc4bf">=</span> ord_map(unique_characters)
</span></span></code></pre></div><p>Le générateur d’expression est plus compact mais fonctionne de même manière.</p>
<h2 id="calculer-les-permutations-la-manière-facile">Calculer les Permutations… La manière facile !</h2>
<p>Tout d’abord, que sont les permutations ? Les permutations sont un concept mathématique. (Il y a actuellement de nombreuses définitions, selon le type de maths que vous faites. Ici, je parle des combinatoires, mais si cela ne vous dit rien, ne vous inquiétez pas. Comme toujours, <a href="https://fr.wikipedia.org/wiki/Permutation" rel="external">Wikipedia est votre ami</a>).</p>
<p>L’idée est de prendre une liste de choses (qui peuvent être des nombres, des lettres, ou des ours dansants) et de trouver toutes les moyens possibles pour les scinder en petites listes. Toutes ces petites listes ont la même taille, qui peuvent aussi petites que 1 et aussi grandes que le nombre total des items.</p>
<p>Oh, rien ne doit être répété. Les mathématiciens disent des choses telles que « trouvons les permutations de 3 items différents pris 2 à la fois » ce qui signifie que vous avez une séquence de 3 items et que vous devez trouver toutes les paires ordonnées possibles.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">itertools</span>                              <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> perms <span style="color:#5bc4bf">=</span> itertools<span style="color:#5bc4bf">.</span>permutations([<span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>, <span style="color:#f99b15">3</span>], <span style="color:#f99b15">2</span>)  <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)                                   <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">1</span>, <span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">2</span>, <span style="color:#f99b15">1</span>)                                            <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">2</span>, <span style="color:#f99b15">3</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">3</span>, <span style="color:#f99b15">1</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">3</span>, <span style="color:#f99b15">2</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)                                   <span style="color:#ef6155">⑤</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">StopIteration</span>
</span></span></code></pre></div><p>① Le module <code>itertools</code> contient toutes sortes de choses amusantes, incluant la fonction <code>permutations()</code> qui fait tout le travail difficile pour trouver les permutations.</p>
<p>② La fonction <code>permutations()</code> prend une séquence (ici une liste de trois entiers) et un nombre, qui est le nombre d’items que vous voulez dans chaque petit groupe. La fonction retourne un itérateur, que vous pouvez utiliser dans une boucle for ou tout autre code qui itère. Ici, je vais parcourir l&rsquo;itérateur manuellement pour afficher toutes les valeurs.</p>
<p>③ La première permutation de <code>[1, 2, 3]</code>, qui prend 2 à la fois, est <code>(1, 2)</code>.</p>
<p>④ Notez que les permutations sont ordonnées : <code>(2, 1)</code>est différent de <code>(1, 2)</code>.</p>
<p>⑤ C’est tout ! Ce sont toutes les permutations de <code>[1, 2, 3]</code> qui prennent 2 à la fois. Les pairs telles que <code>(1, 1)</code> et <code>(2, 2)</code> ne seront jamais vues, parce qu’elles contiennent des répétitions qui ne sont pas des permutations valides.</p>
<p>La fonction <code>permutations()</code> ne nécessite pas de liste. Elle peut prendre n’importe quelle séquence – même une chaîne.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">itertools</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> perms <span style="color:#5bc4bf">=</span> itertools<span style="color:#5bc4bf">.</span>permutations(<span style="color:#48b685">&#39;ABC&#39;</span>, <span style="color:#f99b15">3</span>)  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>)                               <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>(<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> next(perms)
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">StopIteration</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(itertools<span style="color:#5bc4bf">.</span>permutations(<span style="color:#48b685">&#39;ABC&#39;</span>, <span style="color:#f99b15">3</span>))    <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>), (<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>), (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>), (<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;A&#39;</span>)]
</span></span></code></pre></div><p>① Une chaîne est juste une séquence de caractères. Dans le but de trouver des permutations,  la chaîne <code>‘ABC’</code> est équivalente à la liste <code>[‘A’, ‘B’, ‘C’]</code>.</p>
<p>② La première permutation de trois items <code>[‘A’, ‘B’, ‘C’]</code>, qui prennent 3 à la fois, est <code>(‘A’, ‘B’, ‘C’)</code>. Il y a cinq autres permutations. Les trois mêmes caractères dans chaque ordre imaginable.</p>
<p>③ Puisque la fonction <code>permutations()</code> retourne toujours un itérateur, une manière facile de déboguer les permutations est de passer l’itérateur dans la fonction interne <code>list()</code> pour voir toutes les permutations immédiatement.</p>
<h2 id="autres-trucs-amusants-dans-le-module-itertools">Autres trucs amusants dans le module <code>itertools</code></h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">itertools</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(itertools<span style="color:#5bc4bf">.</span>product(<span style="color:#48b685">&#39;ABC&#39;</span>, <span style="color:#48b685">&#39;123&#39;</span>))   <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;1&#39;</span>), (<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>), (<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;3&#39;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;1&#39;</span>), (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>), (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;3&#39;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;1&#39;</span>), (<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>), (<span style="color:#48b685">&#39;C&#39;</span>, <span style="color:#48b685">&#39;3&#39;</span>)]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(itertools<span style="color:#5bc4bf">.</span>combinations(<span style="color:#48b685">&#39;ABC&#39;</span>, <span style="color:#f99b15">2</span>))  <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;B&#39;</span>), (<span style="color:#48b685">&#39;A&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>), (<span style="color:#48b685">&#39;B&#39;</span>, <span style="color:#48b685">&#39;C&#39;</span>)]
</span></span></code></pre></div><p>① La fonction <code>itertools.product()</code> retourne un itérateur contenant le produit cartésien de deux séquences.</p>
<p>② La fonction <code>itertools.combinations()</code> retourne un itérateur contenant toutes les combinaisons possibles d’une séquence donnée d’une longueur donnée. Tout comme la fonction <code>itertools.permutations()</code>, excepté que les combinaisons n’incluent pas les items qui sont la copie d’autres items dans un ordre différent. Ainsi, <code>itertools.permutations('ABC', 2)</code> retournera les deux <code>('A', 'B')</code> et <code>('B', 'A')</code> (entres autres), mais <code>itertools.combinations('ABC', 2)</code> ne retournera pas <code>('B', 'A')</code> parce que c’est une copie de <code>('A', 'B')</code> dans un ordre différent.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names <span style="color:#5bc4bf">=</span> list(open(<span style="color:#48b685">&#39;examples/favorite-people.txt&#39;</span>, encoding<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;utf-8&#39;</span>))  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;Dora</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Ethan</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Wesley</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;John</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Anne</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Mike</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Chris</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Sarah</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Alex</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>, <span style="color:#48b685">&#39;Lizzie</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names <span style="color:#5bc4bf">=</span> [name<span style="color:#5bc4bf">.</span>rstrip() <span style="color:#815ba4">for</span> name <span style="color:#5bc4bf">in</span> names]                             <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;Dora&#39;</span>, <span style="color:#48b685">&#39;Ethan&#39;</span>, <span style="color:#48b685">&#39;Wesley&#39;</span>, <span style="color:#48b685">&#39;John&#39;</span>, <span style="color:#48b685">&#39;Anne&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Mike&#39;</span>, <span style="color:#48b685">&#39;Chris&#39;</span>, <span style="color:#48b685">&#39;Sarah&#39;</span>, <span style="color:#48b685">&#39;Alex&#39;</span>, <span style="color:#48b685">&#39;Lizzie&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names <span style="color:#5bc4bf">=</span> sorted(names)                                                 <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;Alex&#39;</span>, <span style="color:#48b685">&#39;Anne&#39;</span>, <span style="color:#48b685">&#39;Chris&#39;</span>, <span style="color:#48b685">&#39;Dora&#39;</span>, <span style="color:#48b685">&#39;Ethan&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;John&#39;</span>, <span style="color:#48b685">&#39;Lizzie&#39;</span>, <span style="color:#48b685">&#39;Mike&#39;</span>, <span style="color:#48b685">&#39;Sarah&#39;</span>, <span style="color:#48b685">&#39;Wesley&#39;</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names <span style="color:#5bc4bf">=</span> sorted(names, key<span style="color:#5bc4bf">=</span>len)                                        <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> names
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;Alex&#39;</span>, <span style="color:#48b685">&#39;Anne&#39;</span>, <span style="color:#48b685">&#39;Dora&#39;</span>, <span style="color:#48b685">&#39;John&#39;</span>, <span style="color:#48b685">&#39;Mike&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Chris&#39;</span>, <span style="color:#48b685">&#39;Ethan&#39;</span>, <span style="color:#48b685">&#39;Sarah&#39;</span>, <span style="color:#48b685">&#39;Lizzie&#39;</span>, <span style="color:#48b685">&#39;Wesley&#39;</span>]
</span></span></code></pre></div><p>① Cet idiome retourne une liste à partir des lignes d’un fichier texte.</p>
<p>② Malheureusement (dans cet exemple), l’idiome <code>list(open(filename))</code> inclus aussi le retour chariot à la fin de chaque ligne. Cette liste de compréhension utilise la méthode des chaînes <code>rstrip()</code> pour effacer les espaces de fin de chaque ligne. (Les chaînes ont aussi une méthode <code>lstrip()</code> pour supprimer les espaces en début, et une méthode <code>strip()</code> qui supprime les deux).</p>
<p>③ La fonction <code>sorted()</code> prend une liste et la retourne triée. Par défaut, le tri est alphabétique.</p>
<p>④ Mais la fonction <code>sorted()</code> peut aussi prendre une fonction en tant que paramètre <code>key</code>, elle est triée par la clé en question. Dans ce cas, la fonction de tri est <code>len()</code>, ainsi elle est triée par <code>len(each item)</code>. Les noms les plus courts sont en premier, puis de plus en plus longs.</p>
<p>Qu&rsquo;est-ce que cela a à voir avec le module <code>itertools</code> ? Je suis content que vous le demandiez.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#ef6155">…</span>continuing <span style="color:#5bc4bf">from</span> <span style="color:#fec418">the</span> previous interactive shell<span style="color:#ef6155">…</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">itertools</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> groups <span style="color:#5bc4bf">=</span> itertools<span style="color:#5bc4bf">.</span>groupby(names, len)   <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> groups
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;</span>itertools<span style="color:#5bc4bf">.</span>groupby object at <span style="color:#f99b15">0x00BB20C0</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(groups)
</span></span><span style="display:flex;"><span>[(<span style="color:#f99b15">4</span>, <span style="color:#5bc4bf">&lt;</span>itertools<span style="color:#5bc4bf">.</span>_grouper object at <span style="color:#f99b15">0x00BA8BF0</span><span style="color:#5bc4bf">&gt;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#f99b15">5</span>, <span style="color:#5bc4bf">&lt;</span>itertools<span style="color:#5bc4bf">.</span>_grouper object at <span style="color:#f99b15">0x00BB4050</span><span style="color:#5bc4bf">&gt;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#f99b15">6</span>, <span style="color:#5bc4bf">&lt;</span>itertools<span style="color:#5bc4bf">.</span>_grouper object at <span style="color:#f99b15">0x00BB4030</span><span style="color:#5bc4bf">&gt;</span>)]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> groups <span style="color:#5bc4bf">=</span> itertools<span style="color:#5bc4bf">.</span>groupby(names, len)   <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#815ba4">for</span> name_length, name_iter <span style="color:#5bc4bf">in</span> groups:    <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     print(<span style="color:#48b685">&#39;Names with </span><span style="color:#f99b15">{0:d}</span><span style="color:#48b685"> letters:&#39;</span><span style="color:#5bc4bf">.</span>format(name_length))
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     <span style="color:#815ba4">for</span> name <span style="color:#5bc4bf">in</span> name_iter:
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>         print(name)
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>
</span></span><span style="display:flex;"><span>Names <span style="color:#815ba4">with</span> <span style="color:#f99b15">4</span> letters:
</span></span><span style="display:flex;"><span>Alex
</span></span><span style="display:flex;"><span>Anne
</span></span><span style="display:flex;"><span>Dora
</span></span><span style="display:flex;"><span>John
</span></span><span style="display:flex;"><span>Mike
</span></span><span style="display:flex;"><span>Names <span style="color:#815ba4">with</span> <span style="color:#f99b15">5</span> letters:
</span></span><span style="display:flex;"><span>Chris
</span></span><span style="display:flex;"><span>Ethan
</span></span><span style="display:flex;"><span>Sarah
</span></span><span style="display:flex;"><span>Names <span style="color:#815ba4">with</span> <span style="color:#f99b15">6</span> letters:
</span></span><span style="display:flex;"><span>Lizzie
</span></span><span style="display:flex;"><span>Wesley
</span></span></code></pre></div><p>① La fonction <code>itertools.groupby()</code> prend une séquence et une fonction clé, et retourne un itérateur qui génère des paires. Chaque paire contient le résultat de <code>key_function(each item)</code> et un autre itérateur contient tous les items que partage la clé résultante.</p>
<p>② L’appel à la fonction <code>list()</code> a « épuisé » l’itérateur, c’est-à-dire que vous avez déjà généré chaque élément de l&rsquo;itérateur pour créer la liste. Il n’y a pas de bouton “reset” sur un itérateur ; vous ne pouvez pas juste le démarrer une fois qu’il est épuisé. Si vous voulez le parcourir encore par une boucle (dans une nouvelle boucle <code>for</code>), vous devez appeler encore <code>itertools.groupby()</code>  pour créer un nouvel itérateur.</p>
<p>③ Dans cet exemple, à une liste donnée de noms toujours triée par longueur, <code>itertools.groupby(names, len)</code> sortira tous les noms de 4 lettres dans un itérateur, tous les noms de 5 lettres dans un autre, et ainsi de suite. La fonction <code>groupby()</code> est complètement générique ; elle peut regrouper les chaînes par première lettre, les nombres par nombre de facteurs ou toute autre fonction clé imaginable.</p>
<p><strong>La fonction <code>itertools.groupby()</code> fonctionne seulement si la séquence en entrée est déjà triée par la fonction de regroupement. Dans l’exemple ci-dessus, vous avez groupé une liste de noms par la fonction <code>len()</code>. Cela a fonctionné parce que la liste entrée était déjà triée par longueur.</strong></p>
<p>Regardez de plus prés !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(range(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">3</span>))
</span></span><span style="display:flex;"><span>[<span style="color:#f99b15">0</span>, <span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(range(<span style="color:#f99b15">10</span>, <span style="color:#f99b15">13</span>))
</span></span><span style="display:flex;"><span>[<span style="color:#f99b15">10</span>, <span style="color:#f99b15">11</span>, <span style="color:#f99b15">12</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(itertools<span style="color:#5bc4bf">.</span>chain(range(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">3</span>), range(<span style="color:#f99b15">10</span>, <span style="color:#f99b15">13</span>)))        <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>[<span style="color:#f99b15">0</span>, <span style="color:#f99b15">1</span>, <span style="color:#f99b15">2</span>, <span style="color:#f99b15">10</span>, <span style="color:#f99b15">11</span>, <span style="color:#f99b15">12</span>]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(zip(range(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">3</span>), range(<span style="color:#f99b15">10</span>, <span style="color:#f99b15">13</span>)))                    <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">10</span>), (<span style="color:#f99b15">1</span>, <span style="color:#f99b15">11</span>), (<span style="color:#f99b15">2</span>, <span style="color:#f99b15">12</span>)]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(zip(range(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">3</span>), range(<span style="color:#f99b15">10</span>, <span style="color:#f99b15">14</span>)))                    <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">10</span>), (<span style="color:#f99b15">1</span>, <span style="color:#f99b15">11</span>), (<span style="color:#f99b15">2</span>, <span style="color:#f99b15">12</span>)]
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> list(itertools<span style="color:#5bc4bf">.</span>zip_longest(range(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">3</span>), range(<span style="color:#f99b15">10</span>, <span style="color:#f99b15">14</span>)))  <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span>[(<span style="color:#f99b15">0</span>, <span style="color:#f99b15">10</span>), (<span style="color:#f99b15">1</span>, <span style="color:#f99b15">11</span>), (<span style="color:#f99b15">2</span>, <span style="color:#f99b15">12</span>), (<span style="color:#815ba4">None</span>, <span style="color:#f99b15">13</span>)]
</span></span></code></pre></div><p>① La fonction <code>itertools.chain()</code> prend deux itérateurs et retourne un itérateur qui contient tous les items du premier itérateur, suivis de ceux du second itérateur. (Actuellement, il peut prendre n’importe quel nombre d’itérateurs, et les enchaîner dans l’ordre où ils sont passés dans la fonction.)</p>
<p>② La fonction <code>zip()</code> fait quelque chose de prosaïque qui s&rsquo;avère extrêmement utile : elle prend n’importe quel nombre de séquences et retourne un itérateur qui retourne des tuples des premiers items de chaque séquence, ensuite les seconds items de chacune, puis les troisièmes, et ainsi de suite.</p>
<p>③ La fonction <code>zip()</code> s’arrête à la fin de la plus petite séquence. <code>range(10, 14)</code> a 4 items, mais <code>range(10, 14)</code> en a seulement 3, ainsi la fonction <code>zip()</code> retourne un itérateur de 3 items.</p>
<p>④ D’un autre côté, la fonction <code>itertools.zip_longest()</code> s’arrête à la fin de la séquence la plus longue, insérant des valeurs <code>None</code> pour les items passés en fin des séquences plus courtes.</p>
<p>Ok, tout cela est très intéressant, mais quel rapport cela a-t-il avec le résolveur d’alphamétique ? Voici comment :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> characters <span style="color:#5bc4bf">=</span> (<span style="color:#48b685">&#39;S&#39;</span>, <span style="color:#48b685">&#39;M&#39;</span>, <span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;D&#39;</span>, <span style="color:#48b685">&#39;O&#39;</span>, <span style="color:#48b685">&#39;N&#39;</span>, <span style="color:#48b685">&#39;R&#39;</span>, <span style="color:#48b685">&#39;Y&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> guess <span style="color:#5bc4bf">=</span> (<span style="color:#48b685">&#39;1&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>, <span style="color:#48b685">&#39;0&#39;</span>, <span style="color:#48b685">&#39;3&#39;</span>, <span style="color:#48b685">&#39;4&#39;</span>, <span style="color:#48b685">&#39;5&#39;</span>, <span style="color:#48b685">&#39;6&#39;</span>, <span style="color:#48b685">&#39;7&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> tuple(zip(characters, guess))                            <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>((<span style="color:#48b685">&#39;S&#39;</span>, <span style="color:#48b685">&#39;1&#39;</span>), (<span style="color:#48b685">&#39;M&#39;</span>, <span style="color:#48b685">&#39;2&#39;</span>), (<span style="color:#48b685">&#39;E&#39;</span>, <span style="color:#48b685">&#39;0&#39;</span>), (<span style="color:#48b685">&#39;D&#39;</span>, <span style="color:#48b685">&#39;3&#39;</span>),
</span></span><span style="display:flex;"><span> (<span style="color:#48b685">&#39;O&#39;</span>, <span style="color:#48b685">&#39;4&#39;</span>), (<span style="color:#48b685">&#39;N&#39;</span>, <span style="color:#48b685">&#39;5&#39;</span>), (<span style="color:#48b685">&#39;R&#39;</span>, <span style="color:#48b685">&#39;6&#39;</span>), (<span style="color:#48b685">&#39;Y&#39;</span>, <span style="color:#48b685">&#39;7&#39;</span>))
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> dict(zip(characters, guess))                             <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>{<span style="color:#48b685">&#39;E&#39;</span>: <span style="color:#48b685">&#39;0&#39;</span>, <span style="color:#48b685">&#39;D&#39;</span>: <span style="color:#48b685">&#39;3&#39;</span>, <span style="color:#48b685">&#39;M&#39;</span>: <span style="color:#48b685">&#39;2&#39;</span>, <span style="color:#48b685">&#39;O&#39;</span>: <span style="color:#48b685">&#39;4&#39;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#48b685">&#39;N&#39;</span>: <span style="color:#48b685">&#39;5&#39;</span>, <span style="color:#48b685">&#39;S&#39;</span>: <span style="color:#48b685">&#39;1&#39;</span>, <span style="color:#48b685">&#39;R&#39;</span>: <span style="color:#48b685">&#39;6&#39;</span>, <span style="color:#48b685">&#39;Y&#39;</span>: <span style="color:#48b685">&#39;7&#39;</span>}
</span></span></code></pre></div><p>① À une liste donnée de lettres et une liste de chiffres (chacune représentée ici sous forme de chaînes de 1 caractère), la fonction <code>zip()</code> créera une paire de lettres et de chiffres, dans l’ordre.</p>
<p>② Pourquoi est-ce cool ? Parce que cette structure de données se trouve être exactement la bonne structure à transmettre à la fonction <code>dict()</code> pour créer un dictionnaire qui utilise des lettres comme clés et leurs chiffres associés comme valeurs. (Ce n’est bien sûr pas la seule manière de faire cela. Vous pouvez utiliser un <a>dictionnaire de compréhension</a> pour créer directement le dictionnaire). Bien que la représentation imprimée du dictionnaire liste les paires dans un ordre différent (les dictionnaires n&rsquo;ont pas d &lsquo;«ordre» en soi), vous pouvez voir que chaque lettre est associée à un chiffre, en fonction de l&rsquo;ordre d&rsquo;origine des séquences <code>characters</code> et <code>guess</code>.</p>
<p>Le résolveur alphamétique utilise cette technique pour créer un dictionnaire qui fait correspondre chaque lettre dans le puzzle au chiffre, pour chaque solution possible.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>characters <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> sorted_characters)
</span></span><span style="display:flex;"><span>digits <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> <span style="color:#48b685">&#39;0123456789&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> guess <span style="color:#5bc4bf">in</span> itertools<span style="color:#5bc4bf">.</span>permutations(digits, len(characters)):
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">…</span>
</span></span><span style="display:flex;"><span>    equation <span style="color:#5bc4bf">=</span> puzzle<span style="color:#5bc4bf">.</span>translate(dict(zip(characters, guess)))
</span></span></code></pre></div><p>Mais qu’est-ce la méthode <code>translate() </code>?
Ahhh, vous arrivez maintenant la partie <em>réellement</em> amusante.</p>
<h2 id="une-nouvelle-manière-de-manipuler-les-chaînes">Une nouvelle manière de manipuler les chaînes</h2>
<p>Les chaînes Python ont beaucoup de méthodes. Vous avez appris certaines de ces méthodes dans <a>le chapitre Chaînes</a> : <code>lower()</code>, <code>count()</code>, et <code>format()</code>. Maintenant je veux vous présenter une technique de manipulation puissante mais peu connue : la méthode <code>translate()</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> translation_table <span style="color:#5bc4bf">=</span> {ord(<span style="color:#48b685">&#39;A&#39;</span>): ord(<span style="color:#48b685">&#39;O&#39;</span>)}  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> translation_table                         <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>{<span style="color:#f99b15">65</span>: <span style="color:#f99b15">79</span>}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#48b685">&#39;MARK&#39;</span><span style="color:#5bc4bf">.</span>translate(translation_table)       <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;MORK&#39;</span>
</span></span></code></pre></div><p>① La traduction des chaînes débute avec une table de traduction, qui est simplement un dictionnaire qui fait correspondre un caractère avec un autre. Actuellement &ldquo;caractère&rdquo; est incorrect - la table de traduction fait réellement correspondre un <em>octet</em> avec un autre.</p>
<p>② Rappelez-vous, les octets en Python 3 sont des entiers. La fonction <code>ord()</code> retourne la valeur ASCII d&rsquo;un caractère, qui, dans le cas de A-Z, est toujours un octet de 65 à 90.</p>
<p>③ La méthode <code>translate()</code> sur une chaîne prend une table de traduction et la parcourt. Pour cela, elle remplace toutes les occurences des clés de la table de traduction avec les valeurs correspondantes. Dans ce cas, elle &ldquo;traduit&rdquo; <code>MARK</code> en <code>MORK</code>.</p>
<p>Qu&rsquo;est-ce que cela a à voir avec la résolution de puzzles alphamétiques ?
En fait, tout.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> characters <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> <span style="color:#48b685">&#39;SMEDONRY&#39;</span>)       <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> characters
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">83</span>, <span style="color:#f99b15">77</span>, <span style="color:#f99b15">69</span>, <span style="color:#f99b15">68</span>, <span style="color:#f99b15">79</span>, <span style="color:#f99b15">78</span>, <span style="color:#f99b15">82</span>, <span style="color:#f99b15">89</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> guess <span style="color:#5bc4bf">=</span> tuple(ord(c) <span style="color:#815ba4">for</span> c <span style="color:#5bc4bf">in</span> <span style="color:#48b685">&#39;91570682&#39;</span>)            <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> guess
</span></span><span style="display:flex;"><span>(<span style="color:#f99b15">57</span>, <span style="color:#f99b15">49</span>, <span style="color:#f99b15">53</span>, <span style="color:#f99b15">55</span>, <span style="color:#f99b15">48</span>, <span style="color:#f99b15">54</span>, <span style="color:#f99b15">56</span>, <span style="color:#f99b15">50</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> translation_table <span style="color:#5bc4bf">=</span> dict(zip(characters, guess))     <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> translation_table
</span></span><span style="display:flex;"><span>{<span style="color:#f99b15">68</span>: <span style="color:#f99b15">55</span>, <span style="color:#f99b15">69</span>: <span style="color:#f99b15">53</span>, <span style="color:#f99b15">77</span>: <span style="color:#f99b15">49</span>, <span style="color:#f99b15">78</span>: <span style="color:#f99b15">54</span>, <span style="color:#f99b15">79</span>: <span style="color:#f99b15">48</span>, <span style="color:#f99b15">82</span>: <span style="color:#f99b15">56</span>, <span style="color:#f99b15">83</span>: <span style="color:#f99b15">57</span>, <span style="color:#f99b15">89</span>: <span style="color:#f99b15">50</span>}
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#48b685">&#39;SEND + MORE == MONEY&#39;</span><span style="color:#5bc4bf">.</span>translate(translation_table)  <span style="color:#ef6155">④</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;9567 + 1085 == 10652&#39;</span>
</span></span></code></pre></div><p>① En utilisant un <a>générateur d&rsquo;expressions</a>, nous calculons les valeurs d&rsquo;octet pour chaque caractère d&rsquo;une chaîne. <code>characters</code> est un exemple de valeur de <code>sorted_characters</code> dans la fonction <code>alphametics.solve()</code>.</p>
<p>② En utilisant un autre générateur d&rsquo;expression, nous calculons les valeurs d&rsquo;octet de chaque chiffre dans la chaîne. Le résultat, <code>guess</code>, est de la <a>forme retournée par la fonction <code>itertools.permutations()</code></a> dans la fonction <code>alphametics.solve()</code>.</p>
<p>③ Cette table de traduction est générée par <a>itération de <code>characters</code> et de <code>guess</code> ensemble</a> et en construisant un dictionnaire depuis la séquence de pairs résultante. C&rsquo;est exactement ce que fait la fonction <code>alphametics.solve()</code> à l&rsquo;intérieur de la boucle <code>for</code>.</p>
<p>④ Enfin, nous passons cette table de traduction à la méthode <code>translate()</code> du puzzle originale de la chaîne. Cela convertit chaque lettre dans la chaîne vers le chiffre correspondant (basé sur les lettres dans <code>characters</code> et les chiffres dans <code>guess</code>). Le résultat est une expression Python valide, tout comme l&rsquo;est une chaîne.</p>
<p>C&rsquo;est assez impressionnant. Mais que pouvez-vous faire avec une chaîne qui se trouve être une expression Python valide ?</p>
<h2 id="évaluer-arbitrairement-des-chaînes-en-tant-quexpressions-python">Évaluer arbitrairement des chaînes en tant qu&rsquo;expressions Python</h2>
<p>Ceci est la pièce finale du puzzle (ou plutôt, la pièce finale du résolveur de puzzle). Après toutes ces manipulations sympathiques de chaînes, il nous reste une chaîne telle que <code>'9567 + 1085 == 10652'</code>. Mais c&rsquo;est une chaîne, et qu&rsquo;est-ce qui est bon avec une chaîne ? Tapez <code>eval()</code>, l&rsquo;outil universel Python d&rsquo;évaluation.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;1 + 1 == 2&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">True</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;1 + 1 == 3&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">False</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;9567 + 1085 == 10652&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#815ba4">True</span>
</span></span></code></pre></div><p>Mais attendez, il y a plus ! La fonction <code>eval()</code> n&rsquo;est pas limitée aux expressions booléennes. Elle peut capturer toute expression Python et retourner tout type de données.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;&#34;A&#34; + &#34;B&#34;&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;AB&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;&#34;MARK&#34;.translate(</span><span style="color:#f99b15">{65: 79}</span><span style="color:#48b685">)&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;MORK&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;&#34;AAAAA&#34;.count(&#34;A&#34;)&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#39;[&#34;*&#34;] * 5&#39;</span>)
</span></span><span style="display:flex;"><span>[<span style="color:#48b685">&#39;*&#39;</span>, <span style="color:#48b685">&#39;*&#39;</span>, <span style="color:#48b685">&#39;*&#39;</span>, <span style="color:#48b685">&#39;*&#39;</span>, <span style="color:#48b685">&#39;*&#39;</span>]
</span></span></code></pre></div><p>Mais attendez, ce n&rsquo;est pas tout !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> x <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;x * 5&#34;</span>)         <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">25</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;pow(x, 2)&#34;</span>)     <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">25</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">math</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;math.sqrt(x)&#34;</span>)  <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">2.2360679774997898</span>
</span></span></code></pre></div><p>① L&rsquo;expression que prend <code>eval()</code> peut référencer des variables globales définies en-dehors d&rsquo; <code>eval()</code>. Si elle est appelée dans une fonction, elle peut référencer des variables locales, aussi.</p>
<p>② Et des fonctions.</p>
<p>③ Et des modules.</p>
<p>Eh, attendez une minute…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">subprocess</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;subprocess.getoutput(&#39;ls ~&#39;)&#34;</span>)                  <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#39;Desktop         Library         Pictures </span><span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> Documents       Movies          Public   </span><span style="color:#f99b15">\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> Music           Sites&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;subprocess.getoutput(&#39;rm /some/random/file&#39;)&#34;</span>)  <span style="color:#ef6155">②</span>
</span></span></code></pre></div><p>① Le module <code>subprocess</code> vous permet d&rsquo;exécuter arbitrairement des commandes shell et d&rsquo;avoir le résultat en tant que chaîne Python.</p>
<p>② Arbitrairement les commandes shell peuvent avoir des conséquences permanentes.</p>
<p>C&rsquo;est même pire que cela, parce qu&rsquo;il y a la fonction globale <code>__import__()</code> qui prend un nom de module en tant que chaîne, importe le module, et lui retourne une référence. Combinée à la puissance d&rsquo; <code>eval()</code>, vous pouvez construire une expression simple qui supprimera tous vos fichiers :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;__import__(&#39;subprocess&#39;).getoutput(&#39;rm /some/random/file&#39;)&#34;</span>)  <span style="color:#ef6155">①</span>
</span></span></code></pre></div><p>① Maintenant, imaginez la sortie de <code>'rm -rf ~'</code>. En fait, il n’y aurait pas de sortie, mais il ne resterait plus aucun fichier.</p>
<p><strong>eval() is EVIL</strong></p>
<p>Bien, la partie diabolique est d&rsquo;évaluer arbitrairement des expressions depuis des sources non vérifiées. Vous ne devriez utiliser <code>eval()</code> que sur une entrée de confiance. Bien sûr, le truc consiste à déterminer ce qui est «fiable». Mais voici quelque chose que je sais avec certitude : vous <strong>NE DEVRIEZ PAS</strong> prendre ce résolveur alphamétique et le mettre sur Internet en tant que petit service web sympa. Ne faites pas l&rsquo;erreur de penser : &ldquo;Mon Dieu, la fonction fait beaucoup de manipulation de chaîne avant d&rsquo;obtenir une chaîne à évaluer ; je ne peux pas imaginer comment quelqu&rsquo;un pourrait exploiter cela.&rdquo; Quelqu&rsquo;un <strong>comprendra</strong> comment passer furtivement du code exécutable nuisible après toute cette manipulation de chaîne (<a href="http://www.securityfocus.com/blogs/746" rel="external">des choses étranges se sont produites</a>), et vous pourrez alors dire adieu à votre serveur.</p>
<p>Mais il existe sûrement un moyen d’évaluer les expressions en toute sécurité ?
Mettre <code>eval()</code> dans une sandbox où il ne peut accéder à rien ni endommager le reste du monde ?
Eh bien, oui et non.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> x <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">5</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;x * 5&#34;</span>, {}, {})               <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;string&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">NameError</span>: name <span style="color:#48b685">&#39;x&#39;</span> <span style="color:#5bc4bf">is</span> <span style="color:#5bc4bf">not</span> defined
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;x * 5&#34;</span>, {<span style="color:#48b685">&#34;x&#34;</span>: x}, {})         <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">25</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> <span style="color:#5bc4bf">import</span> <span style="color:#fec418">math</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;math.sqrt(x)&#34;</span>, {<span style="color:#48b685">&#34;x&#34;</span>: x}, {})  <span style="color:#ef6155">③</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;string&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">NameError</span>: name <span style="color:#48b685">&#39;math&#39;</span> <span style="color:#5bc4bf">is</span> <span style="color:#5bc4bf">not</span> defined
</span></span></code></pre></div><p>① Le second paramètre et le troisième passés à la fonction <code>eval()</code> agissent dans les espaces de noms global et local pour évaluer l&rsquo;expression. Dans ce cas, les deux sont vides, ce qui signifie alors que, quand la chaîne <code>&quot;x * 5&quot;</code> est évaluée, il n&rsquo;y a pas de référence à <code>x</code> ni dans l&rsquo;espace de nom global ou local, ainsi <code>eval()</code> lève une exception.</p>
<p>② Vous pouvez sélectivement inclure des valeurs spécifiques dans l&rsquo;espace de noms global en les listant individuellement. Alors ces variables - et seulement celles-là - seront disponibles durant l&rsquo;évaluation.</p>
<p>③ Même si vous venez d&rsquo;importer le module <code>math</code>, vous ne pouvez l&rsquo;inclure dans l&rsquo;espace de noms à la fonction <code>eval()</code>, ainsi l&rsquo;évaluation échouera.</p>
<p>Pfff, c&rsquo;était facile. Laissez-moi faire un service web alphamétique, maintenant !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;pow(5, 2)&#34;</span>, {}, {})                   <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">25</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;__import__(&#39;math&#39;).sqrt(5)&#34;</span>, {}, {})  <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">2.2360679774997898</span>
</span></span></code></pre></div><p>① Même si vous avez passé des dictionnaires vides pour les espaces de noms global et local, toutes les fonctions internes de Python seront toujours disponibles durant l&rsquo;évaluation. Ainsi <code>pow(5, 2)</code> fonctionne, parce que <code>5</code> et <code>2</code> sont des littéraux, et que <code>pow()</code> est une fonction interne.</p>
<p>② Malheureusement (et même si vous ne voyez pas pourquoi cela est malheureux, lisez la suite), la fonction <code>__import__()</code> est aussi une fonction interne, ainsi cela fonctionne aussi.</p>
<p>Oui, cela signifie que vous pouvez toujours faire des choses méchantes, même si vous configurez explicitement les espaces de noms global et local pour vider les dictionnaires lors de l&rsquo;appel à <code>eval()</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;__import__(&#39;subprocess&#39;).getoutput(&#39;rm /some/random/file&#39;)&#34;</span>, {}, {})
</span></span></code></pre></div><p>Oups. Je suis heureux de ne pas avoir créer de service web alphamétique.
N&rsquo;y a-t-il aucun moyen d&rsquo;utiliser <code>eval()</code> de manière sécurisée ?
Eh bien, oui et non.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;__import__(&#39;math&#39;).sqrt(5)&#34;</span>,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     {<span style="color:#48b685">&#34;__builtins__&#34;</span>:<span style="color:#815ba4">None</span>}, {})          <span style="color:#ef6155">①</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;string&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">NameError</span>: name <span style="color:#48b685">&#39;__import__&#39;</span> <span style="color:#5bc4bf">is</span> <span style="color:#5bc4bf">not</span> defined
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;__import__(&#39;subprocess&#39;).getoutput(&#39;rm -rf /&#39;)&#34;</span>,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     {<span style="color:#48b685">&#34;__builtins__&#34;</span>:<span style="color:#815ba4">None</span>}, {})          <span style="color:#ef6155">②</span>
</span></span><span style="display:flex;"><span>Traceback (most recent call last):
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;stdin&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>  File <span style="color:#48b685">&#34;&lt;string&gt;&#34;</span>, line <span style="color:#f99b15">1</span>, <span style="color:#5bc4bf">in</span> <span style="color:#5bc4bf">&lt;</span>module<span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">NameError</span>: name <span style="color:#48b685">&#39;__import__&#39;</span> <span style="color:#5bc4bf">is</span> <span style="color:#5bc4bf">not</span> defined
</span></span></code></pre></div><p>① Pour évaluer des expressions non vérifiées de manière sûre, vous avez besoin de définir un dictionnaire d&rsquo;espace de noms global qui fait correspondre <code>&quot;__builtins__&quot;</code> à <code>None</code>, une valeur Python <code>null</code>. En interne, les fonctions &ldquo;built-in&rdquo; sont contenues dans un pseudo-module appelé <code>&quot;__builtins__&quot;</code>. Ce pseudo-module (càd l&rsquo;ensemble des fonctions internes) est rendu disponible aux expressions évaluées à moins que vous les surchargiez explicitement.</p>
<p>② Soyez sûr que vous surchargiez <code>__builtins__</code>. Non pas <code>__builtin__</code>, <code>__built-ins__</code>, ou toute autre variation qui fonctionnera parfaitement mais qui vous expose à des risques catastrophiques.</p>
<p>Ainsi, <code>eval()</code> est sûr maintenant ?
Eh bien, oui et non.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#5bc4bf">&gt;&gt;&gt;</span> eval(<span style="color:#48b685">&#34;2 ** 2147483647&#34;</span>,
</span></span><span style="display:flex;"><span><span style="color:#ef6155">…</span>     {<span style="color:#48b685">&#34;__builtins__&#34;</span>:<span style="color:#815ba4">None</span>}, {})          <span style="color:#ef6155">①</span>
</span></span></code></pre></div><p>① Même sans accéder à <code>__builtins__</code>, vous pouvez toujours lancer une attaque par déni de service. Par exemple, essayer de lever <code>2</code> à la puissance <code>2147483647</code> augmentera l&rsquo;utilisation du CPU de votre serveur à 100% pendant un certain temps. (Si vous essayez cela dans un terminal interactif, appuyez plusieurs fois sur <code>Ctrl-C</code> pour en sortir.) Techniquement cette expression retournera éventuellement une valeur, mais en attendant, votre serveur fera plus rien d&rsquo;autres.</p>
<p>Enfin, il est possible d&rsquo;évaluer en toute sécurité des expressions Python non vérifiées, pour une définition du terme «sûr» qui ne s&rsquo;avère pas très utile dans la vie réelle. C’est bien si vous vous contentez de jouer, et c’est bien si vous ne transmettez que des données fiables. Mais tout autre ne fait que provoquer des ennuis.</p>
<h2 id="résumons-cela-ensemble">Résumons cela ensemble</h2>
<p>Pour récapituler : ce programme résoud des puzzles alphamétiques par force brute, càd, par une recherche exhaustive de toutes les solutions possibles
Pour faire cela, il faut…</p>
<ol>
<li><a>Trouver toutes les lettres dans le puzzle</a> avec la fonction <code>re.findall()</code></li>
<li><a>Trouver toutes les lettres uniques dans le puzzle</a> avec sets et la fonction <code>set()</code></li>
<li><a>Vérifier qu&rsquo;il n&rsquo;y a pas plus de 10 lettres uniques</a> (ce qui signifie que le puzzle est définitivement non résolvable) avec l&rsquo;instruction <code>assert</code></li>
<li><a>Convertir les lettres dans leur équivalent ASCII</a> avec un générateur objet.</li>
<li><a>Calculer toutes les solutions possibles</a> avec la fonction <code>itertools.permutations()</code></li>
<li><a>Convertir chaque solution possible en une expression Python</a> avec la méthode de chaînes <code>translate()</code></li>
<li><a>Tester chaque solution possible en évaluant l&rsquo;expression Python</a> avec la fonction <code>eval()</code></li>
<li>Retourner la première solution qui évalue à <code>True</code></li>
</ol>
<p>… en seulement 14 lignes de code.</p>
<h2 id="lectures-complémentaires-en-anglais">Lectures complémentaires (en anglais)</h2>
<ul>
<li>Le <a href="https://docs.python.org/3.1/library/itertools.html" rel="external">module <code>itertools</code></a></li>
<li><a href="https://pymotw.com/2/itertools/" rel="external"><code>itertools</code> - Fonctions d&rsquo;Itérateur pour boucles efficientes</a></li>
<li>Regarder la <a>Présentation &ldquo;Easy AI with Python&rdquo; de Raymond Hettinger</a> au PyCon 2009. <em>semble ne plus être disponible</em></li>
<li><a href="http://code.activestate.com/recipes/576615-alphametics-solver/?in=user-178123" rel="external">Recette 576615: Résolveur Alphamétique</a>, un résolveur alphamétique original de Raymond Hettinger pour Python 2</li>
<li><a href="http://code.activestate.com/recipes/users/178123/" rel="external">Plus de recettes de Raymond Hettinger</a> dans le référentiel de codes ActiveState</li>
<li><a href="https://en.wikipedia.org/wiki/Verbal_arithmetic" rel="external">Alphamétiques sur Wikipédia</a></li>
<li><a href="http://www.tkcs-collins.com/truman/alphamet/index.shtml" rel="external">Index Alphamétiques</a>, incluant <a href="http://www.tkcs-collins.com/truman/alphamet/alphamet.shtml" rel="external">beaucoup de puzzles</a> et un <a href="http://www.tkcs-collins.com/truman/alphamet/alpha_gen.shtml" rel="external">générateur à fabriquer soi-même</a>.</li>
</ul>
<p>Tout plein de remerciements à Raymond Hettinger pour son accord à modifier la licence de son code, ainsi j&rsquo;ai pu le porter vers Python 3 et l&rsquo;utiliser comme base de ce chapitre.</p>
<p>© 2001–11 Mark Pilgrim</p>
<p>*[ASCII]: American Standard Code for Information Interchange - Code américain normalisé pour l&rsquo;échange d&rsquo;information
*[CPU]: Central Processing Unit - Processeur
*[RAM]: Random Access Memory - Mémoire Vive
*[càd]: c&rsquo;est-à-dire</p>
]]></content>
        <summary type="html"><![CDATA[Relecture du chapitre 8 - Dive into Python pour la communauté DVP]]></summary>
        <published>2019-05-16T20:27:01+01:00</published>
        <updated>2019-05-18T19:07:01+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0dc94430-a689-6e87-57a1-0a79cb9cf47a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-ed25519/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : Création de clé à Courbes Elliptiques Ed25519</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <category term="ed25519" scheme="http://doc.huc.fr.eu.org/fr/tags/ed25519/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il est en effet possible de créer des clés GPG en utilisant l&rsquo;algorithme
à courbe elliptique ED25519.</p>
<p>Ce tutoriel fait suite à ce

<a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">guide de bonnes pratiques de création</a>
 ;
d&rsquo;ailleurs une fois la création terminée, referez-vous y à nouveau.</p>
<p>Avant, assurez-vous d&rsquo;avoir correctement

<a class="inside" href="/fr/sec/gpg/gpg-usage-securise/" title="Lien interne vers l&#39;article : 'GPG : Du bon usage sécurisé'">sécurisé votre configuration GPG</a>
 !</p>
<h2 id="création-parfaite-de-clés-gpg">Création parfaite de clés GPG</h2>
<h3 id="informations-importantes">Informations importantes</h3>
<p>Bien veiller à choisir à la création de clé, l&rsquo;option <code>(9) ECC et ECC</code> - et
ensuite, le type de courbe elliptique désiré - option <code>(1) Curve 25519</code>.</p>
<h3 id="création-en-mode-console">Création en mode console</h3>
<p>Pour l&rsquo;instant, c&rsquo;est la seule possibilité de faire.
Pour cela, il faut utiliser l&rsquo;option <code>--full-gen-key</code> suivie de l&rsquo;option <code>--expert</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --full-gen-key --expert
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 2.2.10; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2018</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Sélectionnez le type de clef désiré :
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span> RSA et RSA <span style="color:#5bc4bf">(</span>par défaut<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span> DSA et Elgamal
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>7<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>9<span style="color:#5bc4bf">)</span> ECC et ECC
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>10<span style="color:#5bc4bf">)</span> ECC <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>11<span style="color:#5bc4bf">)</span> ECC <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>13<span style="color:#5bc4bf">)</span> Clef existante
</span></span><span style="display:flex;"><span>Quel est votre choix ? <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>Sélectionnez le type de courbe elliptique désiré :
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span> Curve <span style="color:#f99b15">25519</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> NIST P-256
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> NIST P-384
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>5<span style="color:#5bc4bf">)</span> NIST P-521
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>6<span style="color:#5bc4bf">)</span> Brainpool P-256
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>7<span style="color:#5bc4bf">)</span> Brainpool P-384
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> Brainpool P-512
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>9<span style="color:#5bc4bf">)</span> secp256k1
</span></span><span style="display:flex;"><span>Quel est votre choix ? <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
</span></span><span style="display:flex;"><span>         <span style="color:#ef6155">0</span> <span style="color:#5bc4bf">=</span> la clef n<span style="color:#48b685">&#39;expire pas
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;  = la clef expire dans n jours
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;w = la clef expire dans n semaines
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;m = la clef expire dans n mois
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;y = la clef expire dans n ans
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Pendant combien de temps la clef est-elle valable ? (0) 2y
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">La clef expire le Thu Jan  7 14:58:16 2021 CET
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Est-ce correct ? (o/N) o
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">GnuPG doit construire une identité pour identifier la clef.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Nom réel : Stéphane HUC
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Adresse électronique : ***@stephane-huc.net
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Commentaire :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Vous utilisez le jeu de caractères « utf-8 ».
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Vous avez sélectionné cette identité :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    « Stéphane HUC &lt;***@stephane-huc.net&gt; »
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Changer le (N)om, le (C)ommentaire, l&#39;</span><span style="color:#5bc4bf">(</span>A<span style="color:#5bc4bf">)</span>dresse électronique
</span></span><span style="display:flex;"><span>ou <span style="color:#5bc4bf">(</span>O<span style="color:#5bc4bf">)</span>ui/<span style="color:#5bc4bf">(</span>Q<span style="color:#5bc4bf">)</span>uitter ? o
</span></span><span style="display:flex;"><span>De nombreux octets aléatoires doivent être générés. Vous devriez faire
</span></span><span style="display:flex;"><span>autre chose <span style="color:#5bc4bf">(</span>taper au clavier, déplacer la souris, utiliser les disques<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>pendant la génération de nombres premiers ; cela donne au générateur de
</span></span><span style="display:flex;"><span>nombres aléatoires une meilleure chance d<span style="color:#48b685">&#39;obtenir suffisamment d&#39;</span>entropie.
</span></span><span style="display:flex;"><span>De nombreux octets aléatoires doivent être générés. Vous devriez faire
</span></span><span style="display:flex;"><span>autre chose <span style="color:#5bc4bf">(</span>taper au clavier, déplacer la souris, utiliser les disques<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>pendant la génération de nombres premiers ; cela donne au générateur de
</span></span><span style="display:flex;"><span>nombres aléatoires une meilleure chance d<span style="color:#48b685">&#39;obtenir suffisamment d&#39;</span>entropie.
</span></span><span style="display:flex;"><span>gpg: clef 0x*********** marquée de confiance ultime.
</span></span><span style="display:flex;"><span>gpg: revocation certificate stored as <span style="color:#48b685">&#39;/home/***/.gnupg/openpgp-revocs.d/***.rev&#39;</span>
</span></span><span style="display:flex;"><span>les clefs publique et secrète ont été créées et signées.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub   ed25519/0x*********** 2019-01-08 <span style="color:#5bc4bf">[</span>SC<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>expire : 2021-01-07<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span> Empreinte de la <span style="color:#ef6155">clef</span> <span style="color:#5bc4bf">=</span> **** **** **** **** **** ****
</span></span><span style="display:flex;"><span>uid                              Stéphane HUC &lt;***@stephane-huc.net&gt;
</span></span><span style="display:flex;"><span>sub   cv25519/0x********** 2019-01-08 <span style="color:#5bc4bf">[</span>E<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>expire : 2021-01-07<span style="color:#5bc4bf">]</span>
</span></span></code></pre></div><h2 id="modification-de-clé">Modification de clé</h2>
<p>Pour modifier une clé GPG, on utilise l&rsquo;option <code>--edit-key</code>
<strong>toujours suivie de</strong> l&rsquo;option <code>--expert</code>.</p>
<h3 id="création-dune-sous-clé">Création d&rsquo;une sous clé</h3>
<p>L&rsquo;action à utiliser est : <code>addkey</code></p>
<p>Veillez à bien choisir l&rsquo;option <code>(10) ECC (signature seule)</code> puis l&rsquo;option
<code>(1) Curve 25519</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg2 --edit-key --expert <span style="color:#48b685">&#34;fingerprint&#34;</span>
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 2.2.12; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2018</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>La clef secrète est disponible.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sec  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : SC
</span></span><span style="display:flex;"><span>     confiance : ultime        validité : ultime
</span></span><span style="display:flex;"><span>ssb  cv25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>  ultime <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; addkey
</span></span><span style="display:flex;"><span>Sélectionnez le type de clef désiré :
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>5<span style="color:#5bc4bf">)</span> Elgamal <span style="color:#5bc4bf">(</span>chiffrement seul<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>6<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>chiffrement seul<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>7<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>10<span style="color:#5bc4bf">)</span> ECC <span style="color:#5bc4bf">(</span>signature seule<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>11<span style="color:#5bc4bf">)</span> ECC <span style="color:#5bc4bf">(</span>indiquez vous-même les capacités<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>12<span style="color:#5bc4bf">)</span> ECC <span style="color:#5bc4bf">(</span>chiffrement seul<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">(</span>13<span style="color:#5bc4bf">)</span> Clef existante
</span></span><span style="display:flex;"><span>Quel est votre choix ? <span style="color:#f99b15">10</span>
</span></span><span style="display:flex;"><span>Sélectionnez le type de courbe elliptique désiré :
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span> Curve <span style="color:#f99b15">25519</span>
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> NIST P-256
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> NIST P-384
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>5<span style="color:#5bc4bf">)</span> NIST P-521
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>6<span style="color:#5bc4bf">)</span> Brainpool P-256
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>7<span style="color:#5bc4bf">)</span> Brainpool P-384
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> Brainpool P-512
</span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">(</span>9<span style="color:#5bc4bf">)</span> secp256k1
</span></span><span style="display:flex;"><span>Quel est votre choix ? <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
</span></span><span style="display:flex;"><span>         <span style="color:#ef6155">0</span> <span style="color:#5bc4bf">=</span> la clef n<span style="color:#48b685">&#39;expire pas
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;  = la clef expire dans n jours
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;w = la clef expire dans n semaines
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;m = la clef expire dans n mois
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">      &lt;n&gt;y = la clef expire dans n ans
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Pendant combien de temps la clef est-elle valable ? (0)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">La clef n&#39;</span>expire pas du tout
</span></span><span style="display:flex;"><span>Est-ce correct ? <span style="color:#5bc4bf">(</span>o/N<span style="color:#5bc4bf">)</span> o
</span></span><span style="display:flex;"><span>Faut-il vraiment la créer ? <span style="color:#5bc4bf">(</span>o/N<span style="color:#5bc4bf">)</span> o
</span></span><span style="display:flex;"><span>De nombreux octets aléatoires doivent être générés. Vous devriez faire
</span></span><span style="display:flex;"><span>autre chose <span style="color:#5bc4bf">(</span>taper au clavier, déplacer la souris, utiliser les disques<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>pendant la génération de nombres premiers ; cela donne au générateur de
</span></span><span style="display:flex;"><span>nombres aléatoires une meilleure chance d<span style="color:#48b685">&#39;obtenir suffisamment d&#39;</span>entropie.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sec  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : SC
</span></span><span style="display:flex;"><span>     confiance : ultime        validité : ultime
</span></span><span style="display:flex;"><span>ssb  cv25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : E
</span></span><span style="display:flex;"><span>ssb  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : jamais      utilisation : S
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>  ultime <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; save
</span></span></code></pre></div><h3 id="gestion-des-préférences-de-hash">Gestion des préférences de Hash</h3>
<p>L&rsquo;action à utiliser est :
<code>setpref SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg2 --edit-key --expert <span style="color:#48b685">&#34;fingerprint&#34;</span>
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 2.2.12; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2018</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>La clef secrète est disponible.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sec  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : SC
</span></span><span style="display:flex;"><span>     confiance : ultime        validité : ultime
</span></span><span style="display:flex;"><span>ssb  cv25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : E
</span></span><span style="display:flex;"><span>ssb  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : jamais      utilisation : S
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>  ultime <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; setpref SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
</span></span><span style="display:flex;"><span>Définir la liste de préférences en :
</span></span><span style="display:flex;"><span>     Chiffrement : AES256, AES192, AES, 3DES
</span></span><span style="display:flex;"><span>     Hachage : SHA512, SHA384, SHA256, SHA1
</span></span><span style="display:flex;"><span>     Compression : ZLIB, BZIP2, ZIP, Non compressé
</span></span><span style="display:flex;"><span>     Fonctionnalités : MDC, Serveur de clefs sans modification
</span></span><span style="display:flex;"><span>Faut-il vraiment mettre à jour les préférences ? <span style="color:#5bc4bf">(</span>o/N<span style="color:#5bc4bf">)</span> o
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sec  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : SC
</span></span><span style="display:flex;"><span>     confiance : ultime        validité : ultime
</span></span><span style="display:flex;"><span>ssb  cv25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : 2022-01-29  utilisation : E
</span></span><span style="display:flex;"><span>ssb  ed25519/0x****************
</span></span><span style="display:flex;"><span>     créé : 2020-01-30  expire : jamais      utilisation : S
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>  ultime <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; save
</span></span></code></pre></div><hr>
<h3 id="autres-actions-utiles">Autres actions utiles</h3>
<p>Et, maintenant, pensez à :</p>
<ul>
<li><a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/#ajout-d-une-photo" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">ajouter une photo</a>
</li>
<li>pour enfin, <a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/#partagez-votre-cl%c3%a9-publique" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">partager votre clé publique</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Tutoriel pour créer une clé GPG en utilisant une courbe elliptique ed25119]]></summary>
        <published>2019-05-12T11:22:33+01:00</published>
        <updated>2020-01-30T20:50:00+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:59c364a7-fcba-f7a6-74e5-04342310ab5c</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nextcloud/nextcloud-php-chroot/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nextcloud Php Chroot OpenBSD (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <category term="chroot" scheme="http://doc.huc.fr.eu.org/fr/tags/chroot/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="présentation-du-problème">Présentation du problème</h2>
<p>Du fait de fonctionner sous OpenBSD, la commande <code>occ</code> ne peut pas s&rsquo;exécuter.
En effet, autant le service web que PHP sont tous les deux sous chroot.</p>
<p>Quand vous exécutez <code>occ</code>, vous obtenez le message d&rsquo;erreur suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Your data directory is invalid
</span></span><span style="display:flex;"><span>Ensure there is a file called <span style="color:#48b685">&#34;.ocdata&#34;</span> in the root of the data directory.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Cannot create <span style="color:#48b685">&#34;data&#34;</span> directory
</span></span><span style="display:flex;"><span>This can usually be fixed by giving the webserver write access to the root directory. See https://docs.nextcloud.com/server/16/go.php?to<span style="color:#5bc4bf">=</span>admin-dir_permissions
</span></span></code></pre></div><p><strong>Résoudre ce problème est simple !</strong></p>
<p>Éditez le fichier de configuration <code>nextcloud/config/config.php</code> et modifiez la
valeur de la variable <code>datadirectory</code>, tel que :</p>
<p><code>'datadirectory' =&gt; ((php_sapi_name() == 'cli') ? '/var/www' : '') . '/htdocs/data',</code></p>
<p>Bien-sûr le chemin <code>/htdocs/data</code> doit correspondre à votre cas réel.</p>
<p>Maintenant vous pouvez utiliser sans soucis la commande <code>occ</code></p>
<p>Néanmoins, n&rsquo;oubliez pas de supprimez la modification avant d&rsquo;utiliser
l&rsquo;interface web, sinon vous ne pourrez pas vous connecter !</p>
<p><em><strong>Problème remarqué par mes soins</strong> : lors du redémarrage du
service PHP et/ou web, cela tend à récrire la variable en préfixant la
variable <em>datadirectory</em> de <em>/var/www/</em>, empêchant le bon fonctionnement
du site web, et provoquant une erreur 500. Si c&rsquo;est votre cas,
ré-éditez le fichier de config et supprimez le préfixe en question.</em></p>
<h3 id="tldr">TL;DR</h3>
<p>Plus simple :</p>
<ul>
<li>Pour &ldquo;activer&rdquo; occ : <br>
<code>sed -i -e 's#/htdocs#/var/www/htdocs#' nextcloud/config/config.php</code></li>
<li>Pour &ldquo;désactiver&rdquo; occ : <br>
<code>sed -i -e 's#/var/www/htdocs#/htdocs#' nextcloud/config/config.php</code></li>
</ul>
<hr>
<h2 id="remerciement">Remerciement</h2>
<p>Je tiens à remercier <a href="https://chargen.one/h3artbl33d/fixing-nextcloud-on-openbsd-with-a-chroot" rel="external">@h3artbl33d</a>
qui a trouvé l&rsquo;astuce… car pendant des mois, cela m&rsquo;a empêché d&rsquo;utiliser la commande <code>occ</code>.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre le problème d&#39;exécution de la commande occ de Nextcloud du fait du chroot sous OpenBSD]]></summary>
        <published>2019-05-02T23:11:15+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ced3a2ef-f02d-ef89-3374-9065bbae8ba7</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/software/firefox-performances/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Firefox : améliorer ses performances</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Firefox" scheme="http://doc.huc.fr.eu.org/fr/tags/firefox/" />
        <category term="performances" scheme="http://doc.huc.fr.eu.org/fr/tags/performances/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un article concernant l&rsquo;amélioration de la Performance de Firefox !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">La modification de la configuration de Firefox peut empêcher
celui-ci de fonctionner - <span class="red">vous êtes seul responsable</span>
de
celle-ci, à vous de vous assurez et de vérifier trois fois plutôt
qu&rsquo;une de vos modifications !</div>

<p>Dans la barre d&rsquo;adresse, tapez la commande <code>about:config</code> puis nous
allons mettre en place différentes informations :</p>
<h2 id="configuration">Configuration</h2>
<h3 id="accélération-matérielle">Accélération matérielle</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Modifier ces configurations peut provoquer des instabilités matérielles !</div>

<p><strong>Préférez</strong> mettre ces options sur <code>true</code> - <em>il est probable que FF utilise
déjà ces options</em></p>
<ul>
<li>Gestion des calques
<ul>
<li><code>layers.acceleration.force-enabled</code></li>
<li><code>layers.async-video.enabled</code></li>
<li><code>layers.offmainthreadcomposition.async-animations</code></li>
<li><code>layers.offmainthreadcomposition.enabled</code></li>
</ul>
</li>
<li>OMTC - Off Main Thread Compositing
<ul>
<li><code>html5.offmainthread</code></li>
</ul>
</li>
<li>WebGL
<ul>
<li><code>webgl.force-enabled</code></li>
</ul>
</li>
</ul>
<h3 id="gestion-des-animations">Gestion des Animations</h3>
<ul>
<li><code>layout.frame_rate.precise</code> - peut atténuer le défilement instable - <strong>préférez</strong> sur <code>true</code></li>
</ul>
<h3 id="gestion-des-images">Gestion des Images</h3>
<ul>
<li><code>image.mem.max_decoded_image_kb</code> - l&rsquo;impact du nombre d&rsquo;images compressées
gérées par FF ; plus la valeur est haute, plus cela améliore la vitesse,
au dépend de l&rsquo;utilisation mémoire.</li>
</ul>
<h3 id="gestion-javascript">Gestion Javascript</h3>
<ul>
<li><code>javascript.options.mem.max</code> : limite la mémoire que Javascript peut
consommer - une valeur <code>-1</code> signifie une gestion automatique</li>
<li><code>javascript.options.mem.high_water_mark</code> : demande au &ldquo;Garbage Collector&rdquo; -
purgeur de mémoire de démarrer quand Javascript atteint tel nombre de mémoire</li>
</ul>
<h3 id="réduction-de-la-mémoire">Réduction de la Mémoire</h3>
<ul>
<li>Gestion du navigateur
<ul>
<li><code>browser.cache.memory.capacity</code> : limite la taille de la mémoire cache, en Mo</li>
<li><code>browser.download.animateNotifications</code> : désactive ou non les notifications
de téléchargement - <strong>préférez</strong> sur <code>false</code></li>
<li><code>browser.sessionhistory.max_entries</code> : limite le nombre maximum de pages
gardées en mémoire dans l&rsquo;historique de la session.</li>
<li><code>browser.sessionstore.max_tabs_undo</code> : limite le nombre maximum d&rsquo;onglets
fermés que vous pouvez ouvrir à nouveau</li>
<li><code>browser.tabs.animate</code> : désactive ou non les animations des onglets -
<strong>préférez</strong> sur <code>false</code></li>
<li><code>config.trim_on_minimize</code> : réduite l&rsquo;usage de la mémoire lorsque la
fenêtre est minimisée - <strong>préférez</strong> sur <code>true</code> - <em>(utile que sous Windows)</em></li>
</ul>
</li>
</ul>
<h2 id="documentations">Documentations</h2>
<ul>
<li>Un <a href="https://gist.github.com/0XDE57/fbd302cef7693e62c769" rel="external">récapitulatif</a> <em>en anglais</em> - dont je me suis fortement inspiré -</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li>merci @<a href="https://www.blog-libre.org/2018/09/22/trucs-et-astuces-volume-2/" rel="external">Cascador</a></li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment améliorer les performances de Firefox]]></summary>
        <published>2019-04-20T15:06:31+02:00</published>
        <updated>2020-04-20T15:24:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:77aa5e1f-e10b-c681-2d4d-bc961c824b3a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/mandoc/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Mandoc : ouvrir les manpages aux formats html, markdown, pdf, ps (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Mandoc" scheme="http://doc.huc.fr.eu.org/fr/tags/mandoc/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Lire les manpages n&rsquo;est pas forcément agréable, voire aisé - heureusement il
est possible avec des outils natifs à OpenBSD de les agrémenter pour en faire
une sortie html, markdown, pdf, postscript puis de les lire dans un lecteur
adéquat.</p>
<p>De petites fonctions pertinentes à se rajouter dans son <code>~/.kshrc</code> qui
utilisent principalement l&rsquo;outil <code>mandoc</code>.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Créer un fichier <code>.fonctions</code> dans votre répertoire personnel, et sourcez-le
dans votre <code>.kshrc</code> personnel - <em>pas besoin de le rendre exécutable</em> ;)</div>

<p>Dans tous les cas, il est possible de modifier à souhait la variable <code>editor</code> :</p>
<h2 id="fonction-man2html">Fonction man2html</h2>
<p>Testé avec <strong>firefox</strong>, <strong>links+</strong>.</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">man2html() {

    editor=firefox
    [ -n &#34;$1&#34; ] &amp;&amp; name=&#34;$1&#34;
    [ -z &#34;$2&#34; ] &amp;&amp; ext=&#34;1&#34; || ext=&#34;$2&#34;
        
    tmp=&#34;/tmp/$name.$ext.html&#34;

    for dir in /usr/share/man /usr/local/man /usr/X11R6/man; do
        [ -f &#34;$dir/man$ext/$name.$ext&#34; ] &amp;&amp; { file=&#34;$dir/man$ext/$name.$ext&#34;; break; }
    done

    [ -f &#34;$file&#34; ] &amp;&amp; mandoc -K utf-8 -T html -O toc &#34;$file&#34; &gt; &#34;$tmp&#34;
    [ -f &#34;$tmp&#34; ] &amp;&amp; $editor &#34;$tmp&#34;

    unset editor ext file name tmp`

}
</code></pre><h3 id="utilisation">Utilisation</h3>
<p><code>man2html nom-manpage numero-section-manpage</code> - s&rsquo;il n&rsquo;y a pas de numéro de
section, alors la fonction essaye d&rsquo;appeler le manpage de la section 1.</p>
<p>Exemple : <code>:$ man2html man</code></p>
<h2 id="fonction-man2md">Fonction man2md</h2>
<p>Testé avec <strong>geany</strong></p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">man2md() {

    editor=geany
    [ -n &#34;$1&#34; ] &amp;&amp; name=&#34;$1&#34;
    [ -z &#34;$2&#34; ] &amp;&amp; ext=&#34;1&#34; || ext=&#34;$2&#34;

    tmp=&#34;/tmp/$name.$ext.md&#34;

    for dir in /usr/share/man /usr/local/man /usr/X11R6/man; do
        [ -f &#34;$dir/man$ext/$name.$ext&#34; ] &amp;&amp; { file=&#34;$dir/man$ext/$name.$ext&#34;; break; }
    done

    [ -f &#34;$file&#34; ] &amp;&amp; mandoc -K utf-8 -T markdown &#34;$file&#34; &gt; &#34;$tmp&#34;
    [ -f &#34;$tmp&#34; ] &amp;&amp; $editor &#34;$tmp&#34; 

    unset editor ext file name tmp`

}
</code></pre><h3 id="utilisation-1">Utilisation</h3>
<p><code>man2md nom-manpage numero-section-manpage</code> - s&rsquo;il n&rsquo;y a pas de numéro
de section, alors la fonction essaye d&rsquo;appeler le manpage de la section 1.</p>
<p>Exemple : <code>:$ man2md hostname.if 5</code></p>
<h2 id="fonction-man2pdf">Fonction man2pdf</h2>
<p>Testé avec <strong>evince</strong>.</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">man2pdf() {

    editor=evince
    [ -n &#34;$1&#34; ] &amp;&amp; name=&#34;$1&#34;
    [ -z &#34;$2&#34; ] &amp;&amp; ext=&#34;1&#34; || ext=&#34;$2&#34;

    tmp=&#34;/tmp/$name.$ext.pdf&#34;

    for dir in /usr/share/man /usr/local/man /usr/X11R6/man; do
        [ -f &#34;$dir/man$ext/$name.$ext&#34; ] &amp;&amp; { file=&#34;$dir/man$ext/$name.$ext&#34;; break; }
    done

    [ -f &#34;$file&#34; ] &amp;&amp; mandoc -K utf-8 -T pdf &#34;$file&#34; &gt; &#34;$tmp&#34;
    [ -f &#34;$tmp&#34; ] &amp;&amp; $editor &#34;$tmp&#34; &amp;&amp; rm -fP &#34;$tmp&#34;

    unset editor ext file name tmp`

}
</code></pre><h3 id="utilisation-2">Utilisation</h3>
<p><code>man2pdf nom-manpage numero-section-manpage</code> - s&rsquo;il n&rsquo;y a pas de
numéro de section, alors la fonction essaye d&rsquo;appeler le manpage de la
section 1.</p>
<p>Exemple : <code>:$ man2pdf man.conf 5</code></p>
<h2 id="fonction-man2ps">Fonction man2ps</h2>
<p>Testé avec <strong>gs</strong>, <strong>ghostview</strong></p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">man2ps() {

    editor=gs
    [ -n &#34;$1&#34; ] &amp;&amp; name=&#34;$1&#34;
    [ -z &#34;$2&#34; ] &amp;&amp; ext=&#34;1&#34; || ext=&#34;$2&#34;

    tmp=&#34;/tmp/$name.$ext.ps&#34;

    for dir in /usr/share/man /usr/local/man /usr/X11R6/man; do
        [ -f &#34;$dir/man$ext/$name.$ext&#34; ] &amp;&amp; { file=&#34;$dir/man$ext/$name.$ext&#34;; break; }
    done

    [ -f &#34;$file&#34; ] &amp;&amp; mandoc -K utf-8 -T ps &#34;$file&#34; &gt; &#34;$tmp&#34;
    [ -f &#34;$tmp&#34; ] &amp;&amp; $editor &#34;$tmp&#34; 

    unset editor ext file name tmp`

}
</code></pre><h3 id="utilisation-3">Utilisation</h3>
<p><code>man2ps nom-manpage numero-section-manpage</code> - s&rsquo;il n&rsquo;y a pas de numéro de section,
alors la fonction essaye d&rsquo;appeler le manpage de la section 1.</p>
<p>Exemple : <code>:$ man2ps dhclient 8</code></p>
<h2 id="fonction-man2doc">Fonction man2doc</h2>
<p>LA fonction qui réunit toutes les précédentes !!!</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">man2doc() {

    #ed2html=firefox 
    #ed2md=geany 
    #ed2pdf=evince 
    #ed2ps=gs

    [ -n &#34;$1&#34; ] &amp;&amp; format=&#34;$1&#34;
    [ -n &#34;$2&#34; ] &amp;&amp; name=&#34;$2&#34;
    [ -z &#34;$3&#34; ] &amp;&amp; nb=&#34;1&#34; || nb=&#34;$3&#34;

    #eval &#34;editor=\${ed2$format}&#34;

    tmp=&#34;/tmp/$name.$nb.$format&#34;
    [ -f &#34;$tmp&#34; ] &amp;&amp; rm -fP &#34;$tmp&#34;

    case &#34;$format&#34; in 
        &#34;md&#34;) type=&#34;markdown&#34; ;;
        *) type=&#34;$format&#34; ;;
    esac

    for file in $(find /usr/{local,share,X11R6}/man/ -name $name.$nb); do mandoc -K utf-8 -T &#34;$type&#34; &#34;$file&#34; &gt;&gt; &#34;$tmp&#34;; done

    [ -f &#34;$tmp&#34; ] &amp;&amp; xdg-open &#34;$tmp&#34;    # $editor

    unset editor file format name nb tmp

}
</code></pre><h3 id="utilisation-4">Utilisation</h3>
<p>À la différence des précédentes fonctions, cette dernière cherchera tous
les manpages correspondants, et les incluera les uns à la suite des autres…</p>
<p><code>man2doc format-fichier nom-manpage numero-section-manpage</code>.</p>
<ul>
<li><code>format-fichier</code> : <code>html</code>, <code>md</code>, <code>pdf</code>, ou <code>ps</code></li>
<li>Toujours si le numéro de section n&rsquo;est pas spécifié, la fonction cherchera dans la section 1.</li>
</ul>
<p>Exemples :</p>
<ul>
<li><code>:$ man2doc html man</code></li>
<li><code>:$ man2doc pdf doas.conf 5</code></li>
<li><code>:$ man2doc md makewhatis 8</code></li>
<li><code>:$ man2doc ps vmm 4</code></li>
</ul>
<hr>
<p><em>Inspiré par
<a href="https://miamondo.org/2018/12/24/ouvrir-les-pages-man-directement-dans-son-editeur-pour-un-meilleur-confort-de-lecture/" rel="external">Mi@mondo</a></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuces pour ouvrir les manpages aux formats HTML, MarkDown, PDF, PS grâce à Mandoc sous OpenBSD]]></summary>
        <published>2018-12-28T01:35:16+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:73babdf2-568a-f906-8669-ca434bd26c0d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/vm-debian-9-stretch/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [OpenBSD :: Virtualisation] Debian Stretch (9.x)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Virtualisation" scheme="http://doc.huc.fr.eu.org/fr/tags/virtualisation/" />
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Stretch" scheme="http://doc.huc.fr.eu.org/fr/tags/stretch/" />
        <category term="vmd" scheme="http://doc.huc.fr.eu.org/fr/tags/vmd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La virtualisation de machine virtuelle sous OpenBSD est officiellement
disponible nativement dans le système de base depuis OpenBSD 5.9. <br>
Néanmoins, la <strong>FAQ Virtualisation</strong> (<a href="https://www.openbsd.org/faq/faq16.html" rel="external">EN</a>) apparaît à partir d&rsquo;OpenBSD 6.4 -
<em>(preuve d&rsquo;une certaine maturité !?)</em></p>
<ul>
<li>Version : <strong>native</strong></li>
<li>OS : OpenBSD <strong>6.4</strong>, <strong>6.5</strong></li>
</ul>
<h2 id="installation">Installation</h2>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p><strong>ATTENTION</strong> : Ce tutoriel ne documente pas dans les moindres détails les phases
d&rsquo;installation, voire de configuration.</p>
<p>Il est <strong>VRAIMENT</strong> nécessaire de faire preuve de réflexion, discernement et
d&rsquo;avoir un minimum de compétences, pour comprendre les liens entre les différentes
briques !</p>
<p>Merci de votre compréhension…</p>
</div>

<h3 id="petites-précisions">Petites précisions</h3>
<p>Il existe au moins deux manières d&rsquo;installer Debian dans une VM.</p>
<ul>
<li>
<p>la première méthode - <em>la plus simple</em> - par le biais de l&rsquo;outil <a href="/fr/sys/openbsd/vm-debian-9-stretch/#avec-qemu">qemu</a>.</p>
</li>
<li>
<p>la seconde native à OpenBSD avec la commande <a href="/fr/sys/openbsd/vm-debian-9-stretch/#avec-vmctl">vmctl</a>.</p>
</li>
</ul>
<h3 id="précisions-de-commandes">Précisions de commandes</h3>
<p>Pour information, les commandes précédées du symbole <code>$</code> sont à exécuter en tant
qu&rsquo;utilisateur ; celles précédées du symbole <code>#</code> le sont avec des droits
administrateurs, soit en tant que <em>root</em>, soit par l&rsquo;usage de la commande

<a class="man" href="https://man.openbsd.org/doas" title="Page du Manuel OpenBSD pour : doas">doas</a>
.</p>
<h3 id="précisions-réseaux">Précisions réseaux</h3>
<ul>
<li>
<p>L&rsquo;interface <code>vether0</code> de l&rsquo;hôte aura pour adresse IPv4 : <code>192.168.0.1</code>, cette
adresse IP sera l&rsquo;adresse de la passerelle pour l&rsquo;interface réseau de la VM.</p>
</li>
<li>
<p>L&rsquo;interface <code>enp0s3</code> de la VM Debian aura pour adresse IPv4 : <code>192.168.0.2</code>…</p>
</li>
<li>
<p>Dans les deux cas, le masque de réseau est de 24 bits.</p>
</li>
<li>
<p>Le serveur DNS renseigné dans le fichier <code>/etc/resolv.conf</code> de la VM de Debian
est, par convention <code>1.1.1.1</code>. C&rsquo;est celui de Cloudfare. Mais il peut être
très bien tout autre, pourvu qu&rsquo;il soit respectueux de la confidentialité… <br>
tel que ceux de Quad9, par exemple !</p>
</li>
<li>
<p>Ce même serveur DNS peut être renseigné dans la règle PF de redirection de
flux DNS vers la VM.</p>
</li>
</ul>
<h3 id="pré-requis">Pré-requis</h3>
<p>Il est nécessaire que votre machine sur laquelle vous souhaitez virtualiser ait
un CPU compatible avec les fonctions adéquates. Pour le vérifier, tapez dans
votre terminal/console la commande suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>:$ dmesg | egrep <span style="color:#48b685">&#39;(VMX/EPT|SVM/RVI)&#39;</span>
</span></span></code></pre></div><p>La réponse du système doit être :</p>
<p>⇒ pour CPU Intel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT
</span></span></code></pre></div><p>⇒ pour CPU Amd :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ksh" data-lang="ksh"><span style="display:flex;"><span>vmm0 at mainbus0: SVM/RVI
</span></span></code></pre></div><p>Si aucune ligne n&rsquo;apparaît, aucune virtualisation ne sera possible. Par
acquis de conscience, vérifiez votre BIOS|UEFI que celle-ci ne soit pas
désactivée.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>De même, en rapport avec les failles CPU relatives à Meltdown, Spectre, certains
CPU Intel sont patchés pour remédier à <a href="https://www.intel.fr/content/www/fr/fr/architecture-and-technology/l1tf.html" rel="external">L1TF</a>.
Sous OpenBSD, ces CPU reçoivent un correctif approprié. Malheureusement, cela
impacte la virtualisation et rend celle-ci impossible. <br>
Vous pouvez vous retrouver dans la situation où vous auriez un CPU compatible,
mais dans les faits, la virtualisation ne pourrait être pleinement fonctionnelle.</p>
<p><em>Préférez AMD, en attendant ARM…</em></p>
</div>

<hr>
<p>Il est nécessaire d&rsquo;installer le firmware <code>vmm</code> pour que le kernel gère.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# fw_update vmm
</span></span></code></pre></div><hr>
<p>Par convention, créons un répertoire <em>vm</em> dans notre répertoire personnel, et
nous travaillerons à partir de celui-ci : <br>
<code>$ mkdir vm &amp;&amp; cd vm</code></p>
<p><em>Bien-sûr, vous pouvez travailler à partir de n&rsquo;importe quel répertoire - <br>
débrouillez-vous !</em></p>
<h3 id="création-de-limage-qcow2">Création de l&rsquo;image qcow2</h3>
<p>Dans les deux cas présentés, nous commencerons par créer la VM, très
simplement avec l&rsquo;outil natif à OpenBSD, nommé <em>vmctl</em> : <br>
<code># vmctl create ~/vm/debian.qcow2 -s 10G</code></p>
<p><em>(bien-sûr, vous pouvez changer la taille de la nouvelle VM en spécifiant une
autre…)</em></p>
<h3 id="téléchargement-de-liso-debian">Téléchargement de l&rsquo;iso Debian</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION, vérifiez à l&rsquo;URL suivante le nom de l&rsquo;image iso de debian : <br>
<code>https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/</code> <br>
Et, modifiez en conséquence le code ci-dessous !</div>

<p>Ensuite, téléchargeons l&rsquo;iso Debian : <br>
<code>:$ ftp https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/{debian-9.7.0-amd64-netinst.iso,SHA512SUMS}</code></p>
<p>Une fois téléchargée, vérifions sa somme de contrôle :</p>
<pre tabindex="0"><code>:$ sha512 -C SHA512SUMS debian-9.7.0-amd64-netinst.iso
(SHA512) debian-9.7.0-amd64-netinst.iso: OK
</code></pre><p>Si <em>OK</em>, alors c&rsquo;est bon… <br>
sinon, re-téléchargez !</p>
<h3 id="avec-qemu">Avec Qemu</h3>
<p>Cette méthode est la plus facile, mais non conventionnelle.</p>
<p>Pour pouvoir créer une VM avec cette méthode <em>(ou tout autre
distribution GNU/Linux dedans…)</em>, il est nécessaire d&rsquo;utiliser le
paquet <em>qemu</em> : <br>
<code>:# pkg_add qemu</code></p>
<p>Puis exécutez <em>qemu</em> pour faire l&rsquo;installation de Debian dans la VM -
<em>que nous ne détaillerons pas, puisque c&rsquo;est exactement comme sur
toute machine permettant de faire fonctionner Debian</em> : <br>
<code>:$ qemu-system-x86_64 -hda ~/vm/debian.qcow2 -cdrom debian*.iso -boot d</code> <br>
à un détail près est qu&rsquo;il vaut mieux à la fin de l&rsquo;installation de
Debian ne pas redémarrer par le biais de l&rsquo;installateur Debian, mais de
choisir le menu &rsquo;exit&rsquo; pour venir dans le shell, et d&rsquo;exécuter la
commande : <br>
<code># halt</code> - <br>
<em>ou son équivalent <code># shutdown -h now</code></em> - qui permettra d&rsquo;arrêter proprement la VM.</p>
<p>Ensuite, passons à la <a href="/fr/sys/openbsd/vm-debian-9-stretch/#configuration">configuration</a>… <br>
puis démarrons la VM <em>debian</em> : <br>
<code>:$ vmctl start debian -c</code></p>
<p>Puis une fois connecté, avec des droits administrateurs, il faut modifier le
fichier <code>/etc/defaut/grub</code> de telle manière :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">GRUB_TIMEOUT</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">GRUB_CMDLINE_LINUX_DEFAULT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">GRUB_CMDLINE_LINUX</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;console=tty1 console=ttyS0,115200&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">GRUB_TERMINAL</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;console serial&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">GRUB_SERIAL_COMMAND</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1&#34;</span>
</span></span></code></pre></div><p>Puis de mettre à jour grub : <code># update-grub</code></p>
<p>Redémarrez votre debian, et profitez de son usage !</p>
<p>Une fois terminée, vous pouvez en <a href="/fr/sys/openbsd/vm-debian-9-stretch/#pour-finir">finir</a> avec la configuration… <br>
Voilà !</p>
<hr>
<h3 id="avec-vmctl">Avec vmctl</h3>
<p>Cette méthode est un peu plus &ldquo;sioux&rdquo;, mais ne nécessite que des outils natifs
à OpenBSD.</p>
<p>Nous allons utiliser l&rsquo;image de démarrage avec le fichier <code>initrd</code> modifié pour
Xen pour fonctionner avec…</p>
<h3 id="téléchargement">Téléchargement</h3>
<p>Téléchargeons les fichiers nécessaires :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ftp http://ftp.debian.org/debian/dists/stretch/main/installer-amd64/current/images/hd-media/boot.img.gz
</span></span><span style="display:flex;"><span>:$ ftp http://ftp.debian.org/debian/dists/stretch/main/installer-amd64/current/images/netboot/xen/initrd.gz
</span></span><span style="display:flex;"><span>:$ ftp http://ftp.debian.org/debian/pool/main/l/linux/virtio-modules-4.9.0-8-amd64-di_4.9.135-1_amd64.udeb
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Au moment où vous lirez ce tutoriel, le nom exact du paquet <code>virtio-modules</code>
pourrait avoir changé… <br>
donc parcourez le site <a href="http://ftp.debian.org/debian/pool/main/l/linux/" rel="external">Debian</a>
pour trouver la version la plus récente !</div>

<h3 id="décompressions">Décompressions</h3>
<p>Occupons-nous des différents phases de décompression des trois fichiers
téléchargés :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gzip -d initrd.gz
</span></span><span style="display:flex;"><span>:$ mkdir stable
</span></span><span style="display:flex;"><span>:$ cd stable
</span></span><span style="display:flex;"><span>:$ ar -x ../virtio-modules-4.9.0-**-1_amd64.udeb data.tar.xz &lt;<span style="color:#5bc4bf">=</span> remplacez par le nom du paquet <span style="color:#48b685">`</span>virtio-modules<span style="color:#48b685">`</span> que vous avez téléchargé !
</span></span><span style="display:flex;"><span>:$ xz -d data.tar.xz
</span></span><span style="display:flex;"><span>:$ tar xf data.tar
</span></span><span style="display:flex;"><span>:$ rm data.tar
</span></span><span style="display:flex;"><span>:$ find . | cpio -o -A -H sv4cpio -O ../initrd
</span></span><span style="display:flex;"><span>:$ cd ..
</span></span><span style="display:flex;"><span>:$ gzip -9 initrd
</span></span><span style="display:flex;"><span>:$ gzip -d boot.img.gz
</span></span></code></pre></div><h3 id="modifications">Modifications</h3>
<p>Il nous faut monter le fichier <code>boot.img</code> afin de faire les modifications
systèmes nécessaires :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# vnconfig vnd1 ~/vm/boot.img
</span></span><span style="display:flex;"><span>:# mount /dev/vnd1i /mnt
</span></span><span style="display:flex;"><span>:# cp initrd.gz /mnt/INITRD.GZ
</span></span><span style="display:flex;"><span>:# sed -i -e <span style="color:#48b685">&#34;s/\(.*\)append vga=788 initrd=initrd.gz --- quiet/\1append vga=off initrd=initrd.gz --- quiet console=ttyS0,115200n8/&#34;</span> /mnt/TXT.CFG
</span></span><span style="display:flex;"><span>:# umount /mnt
</span></span><span style="display:flex;"><span>:# vnconfig -u vnd1
</span></span></code></pre></div><p>Ensuite, passons à la <a href="/fr/sys/openbsd/vm-debian-9-stretch/#configuration">configuration</a>… <br>
puis, démarrons la VM <em>install</em>.</p>
<h3 id="démarrage">Démarrage</h3>
<p><code>:$ vmctl start install -c</code></p>
<p>Lorsque le menu d&rsquo;installation est affiché, choisir <em>Install</em>, puis une fois
dans l&rsquo;installateur, appuyez sur la touche <key>ESC/ECHAP</key> pour choisir le
menu <em>Execute a shell</em>.</p>
<p>Une fois dans le shell, il faut taper les commandes qui suivent :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>depmod
</span></span><span style="display:flex;"><span>modprobe virtio_pci virtio_blk
</span></span><span style="display:flex;"><span>lsmod
</span></span><span style="display:flex;"><span>exit
</span></span></code></pre></div><p>puis, continuer la phase d&rsquo;installation selon vos besoins.</p>
<p>Une fois l&rsquo;installation terminée, ne redémarrez pas par le biais de l&rsquo;installateur,
choisissez à nouveau d&rsquo;exécuter le shell, puis écrivez la commande : <code># halt</code>
afin d&rsquo;arrêter la VM proprement !</p>
<h3 id="re-démarrage">Re-démarrage</h3>
<p>Maintenant, il faut démarrer la VM <em>debian</em> : <br>
<code>$ vmctl start debian -c</code> <br>
afin de pouvoir voir le menu de Grub et l&rsquo;éditer - <em>si vous le ratez, vous
démarrez en mode <code>initramfs</code> et vous serez bon pour recommencer à démarrer la
VM afin d&rsquo;arriver à éditer le Grub !</em></p>
<p>Il faut éditer le menu Grub ; tapez sur la touche <key>e</key> puis cherchez
toutes les occurrences de <code>vdb</code> pour les transformer en <code>vda</code> -
<span class="red">ne touchez pas au numéro qui suit</span>
, autrement vous
vous retrouveriez au prochain démarrage avec le même problème que décrit ci-dessus… <br>
Une fois modifié, appuyez sur les touches <key>CTRL+x</key> pour sortir de
l&rsquo;éditeur de Grub et démarrez le système Debian fraîchement installé !</p>
<p>Une fois connecté, avec des droits administrateurs, il faut éditer le fichier
<code>/boot/grub/grub.cfg</code> pour remplacer les mêmes occurrences de <code>vdb</code> en <code>vda</code>,
puis d&rsquo;exécuter la commande <code>update-grub</code>.</p>
<p>Pour finir, il faut éditer le fichier <code>/etc/network/interfaces</code> pour
remplacer le nom de l&rsquo;interface <code>enp0s4</code> par <code>enp0s3</code> : <br>
<code># sed -i -e 's/enp0s4/enp0s3/' /etc/network/interfaces</code></p>
<p>Maintenant vous pouvez redémarrer votre système Debian pour en profiter
convenablement !</p>
<p>Une fois terminée, vous pouvez en <a href="/fr/sys/openbsd/vm-debian-9-stretch/#pour-finir">finir</a> avec la configuration… <br>
Voilà !</p>
<hr>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration se trouve être <code>/etc/vm.conf</code>. Il faut écrire votre
compte identifiant dans la variable <code>USER</code>, cela permettra à votre utilisateur
d&rsquo;utiliser l&rsquo;outil <code>vmctl</code>…</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">USER</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">ROOT</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/home/</span><span style="color:#ef6155">$USER</span><span style="color:#48b685">/vm&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>switch <span style="color:#48b685">&#34;sw&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    interface bridge0
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>vm <span style="color:#48b685">&#34;install&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    disable
</span></span><span style="display:flex;"><span>    memory 1024M
</span></span><span style="display:flex;"><span>    disk <span style="color:#ef6155">$ROOT</span>/boot.img
</span></span><span style="display:flex;"><span>    disk <span style="color:#ef6155">$ROOT</span>/debian.qcow2
</span></span><span style="display:flex;"><span>    interface <span style="color:#5bc4bf">{</span> switch <span style="color:#48b685">&#34;sw&#34;</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>    owner <span style="color:#ef6155">$USER</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>vm <span style="color:#48b685">&#34;debian&#34;</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>    disable
</span></span><span style="display:flex;"><span>    memory 1024M
</span></span><span style="display:flex;"><span>    disk <span style="color:#ef6155">$ROOT</span>/debian.qcow2
</span></span><span style="display:flex;"><span>    interface <span style="color:#5bc4bf">{</span> switch <span style="color:#48b685">&#34;sw&#34;</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>    owner <span style="color:#ef6155">$USER</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><hr>
<p>Vérifiez la configuration à l&rsquo;aide de l&rsquo;option <code>-n</code> de vmd :</p>
<p><code>:$ vmd -n</code></p>
<hr>
<p>Après avoir configuré les <a href="/fr/sys/openbsd/vm-debian-9-stretch/#interfaces-reseaux">interfaces réseaux</a>, il faudra
démarrer le service <code>vmd</code>.</p>
<p>Il est assurément utile de s&rsquo;occuper de la <a href="/fr/sys/openbsd/vm-debian-9-stretch/#nat">traduction d&rsquo;adresses réseaux</a>,
et aussi des <a href="/fr/sys/openbsd/vm-debian-9-stretch/#pf">règles du parefeu</a>…</p>
<h3 id="interfaces-réseaux">Interfaces réseaux</h3>
<p>Créons les interfaces réseaux nécessaires que sont <code>vether0</code> et <code>bridge0</code> qui
permettront un contrôle fin de l&rsquo;adressage IP et des règles PF.</p>
<p>Pour l&rsquo;interface <code>vether0</code>, il est possible d&rsquo;utiliser n&rsquo;importe quelle classe
privée IPv4 <em>(A: 10.0/8 ; B: 172.0.0/16 ; C: 192.168.0.0/24)</em> - nous utiliserons
un type de classe C privée, telle que <code>192.168.0.x*</code>. <br>
<em>Après tout, nous n&rsquo;avons pas plus de 256 VM à administrer</em>… ;)</p>
<h3 id="bridge0">bridge0</h3>
<p>Le fichier relatif est <code>/etc/hostname.bridge0</code> : <code>add vether0</code></p>
<h3 id="vether0">vether0</h3>
<p>Le fichier relatif est <code>/etc/hostname.vether0</code> : <code>inet 192.168.0.1 255.255.255.0</code></p>
<hr>
<p>Une fois les fichiers d&rsquo;interfaces créés, donnez des droits 0600 dessus, puis
démarrez les deux interfaces :</p>
<pre tabindex="0"><code>:# chmod 0600 /etc/hostname.{bridge,vether}0
:# sh /etc/netstart {bridge,vether}0
</code></pre><h3 id="nat">NAT</h3>
<p>Pour nous faciliter la vie avec notre futur VM, nous allons autoriser la
redirection des paquets IP, pour qu&rsquo;elle puisse communiquer sur Internet -
<em>ne serait-ce que pour faire les mises à jour</em>…</p>
<p>Dans un terminal/console, écrivez :</p>
<pre tabindex="0"><code>:# sysctl net.inet.ip.forwarding=1
:# sysctl net.inet6.ip6.forwarding=1
</code></pre><p>La première ligne est pour IPv4, la seconde pour IPv6.</p>
<p>Puis, pour garder les paramètres au redémarrage, modifiez le fichier
<code>/etc/sysctl.conf</code> pour ajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">net.inet.ip.forwarding</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">net.inet6.ip6.forwarding</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si vous ne voulez pas que votre VM soit &ldquo;visible&rdquo; sur le réseau, n&rsquo;activez pas
la traduction d&rsquo;adresses réseaux !</div>

<h3 id="pf">PF</h3>
<p>Il sera ensuite nécessaire de modifier le fichier <em>/etc/pf.conf</em> ajouter
au moins les règles suivantes :</p>
<pre tabindex="0"><code>(…)

match out on egress from vether0:network to any nat-to (egress)

(…)

pass in quick proto { udp tcp } from vether0:network to any port domain rdr-to 1.1.1.1 port domain
pass on vether0 from 127.0.0.1 to any
pass on vether0 from vether0:network to any

(…)
</code></pre><ul>
<li>
<p>La première règle indique que tout ce qui vient du réseau lié à l&rsquo;interface
<code>vether0</code> doit être traduit (NATé) vers les adresses IP faisant partie du
groupe <code>egress</code></p>
</li>
<li>
<p>La deuxième règle demande à ce que tout flux entrant qui vient du service
<code>domain</code> (port <code>53</code>) sur les protocoles <code>udp</code> et <code>tcp</code> depuis le réseau lié
à l&rsquo;interface <code>vether0</code> soit redirigé vers le service en question. <br>
<em>L&rsquo;adresse IPv4 <code>1.1.1.1</code> est celle du serveur DNS de Cloudflare ; elle
peut être très bien celle de tout autre serveur DNS</em>.</p>
</li>
<li>
<p>La troisième règle autorise tout ce qui passe en entrée et en sortie sur
l&rsquo;interface <code>vether0</code> depuis l&rsquo;interface <code>locale</code>  vers ailleurs…</p>
</li>
<li>
<p>Quant à la quatrième, elle autorise tout du réseau, en entrée et en sortie,
lié à l&rsquo;interface <code>vether0</code> vers partout !</p>
</li>
</ul>
<hr>
<h2 id="pour-finir">Pour finir</h2>
<p>Une fois que vous avez fini l&rsquo;installation de Debian dans votre VM, que vous
avez fait les derniers réglages nécessaires pour son bon fonctionnement, vous
pouvez faire deux choses utiles liés à l&rsquo;édition du fichier <code>/etc/vm.conf</code> :</p>
<ul>
<li>
<p>Supprimer/commenter toute écriture relative à la déclaration de la VM <code>install</code>…</p>
</li>
<li>
<p>Remplacer le mot clé <code>disable</code> par <code>enable</code> pour la VM <code>debian</code> - si vous
désirez que la VM correspondante démarre, soit lors du démarrage de votre
machine, si et seulement si le service <code>vmd</code> est bien actif et démarré lors
du processus de démarrage machine, soit lorsque vous redémarrez le service
<code>vmd</code> lui-même par vos soins.</p>
</li>
</ul>
<p>Un tout petit laïus sur la commande <em>vmctl</em> : <code>$ man vmctl</code> pour découvrir les
différentes options bien utiles, dont <em>show</em>, <em>status</em>, <em>start</em>, et <em>stop</em> qu&rsquo;il
semble nécessaire de maîtriser !</p>
<hr>
<h2 id="dépannage">Dépannage</h2>
<h3 id="vmctl-vmm-bios-firmware-not-found">vmctl vmm bios firmware not found</h3>
<p>Vous n&rsquo;avez tout simplement pas installé le firmware <strong>vmm</strong> !</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>
<p>Merci de lire la documentation officielle <strong>FAQ Virtualisation</strong>
(<a href="https://www.openbsd.org/faq/faq16.html" rel="external">EN</a>, [FR][2]) afin de bien comprendre le sujet, les différentes
informations nécessaires à une meilleure préhension de celui-ci.</p>
</li>
<li>
<p>Il est fortement intéressant de lire les pages de manuels, en anglais,
relative à :</p>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/vmctl.8" title="Page du Manuel OpenBSD pour : vmctl">vmctl(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vmd.8" title="Page du Manuel OpenBSD pour : vmd">vmd(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vm.conf.5" title="Page du Manuel OpenBSD pour : vm.conf">vm.conf(5)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/vmm.4" title="Page du Manuel OpenBSD pour : vmm">vmm(4)</a>
</li>
<li>sans oublier 
<a class="man" href="https://man.openbsd.org/doas" title="Page du Manuel OpenBSD pour : doas">doas</a>
, au besoin…</li>
</ul>
</li>
</ul>
<h3 id="autres-sources">Autres Sources</h3>
<ul>
<li><a href="http://www.netzbasis.de/openbsd/vmd-debian/" rel="external">http://www.netzbasis.de/openbsd/vmd-debian/</a></li>
</ul>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Virtualiser Debian Stretch (9.x) sous OpenBSD grâce à vmd]]></summary>
        <published>2018-12-25T18:04:24+01:00</published>
        <updated>2019-10-15T23:43:24+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:11504df3-5adf-b243-6c80-7edd46857713</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/nextcloud/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Service Nextcloud / nginx ( &#43; Office Online, Talk )</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Nextcloud" scheme="http://doc.huc.fr.eu.org/fr/tags/nextcloud/" />
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p><strong>Nextcloud</strong> est un logiciel de nuage informatique afin de partager depuis et
sur Internet des fichiers mais aussi un ou plusieurs agendas, des contacts, des
notes, etc… de manière modulaire.</p>
<ul>
<li>Site web : <a href="https://www.nextcloud.com" rel="external">https://www.nextcloud.com</a></li>
<li>Version installable :
<ul>
<li>depuis les paquets : <strong>6.4</strong> : <em>14.0.1</em> ; <strong>6.5</strong> : <em>15.0.5p1</em> ; <strong>6.6</strong> : <em>17.0</em></li>
<li>depuis le <a href="https://nextcloud.com/install/#instructions-server" rel="external">site web</a> !</li>
</ul>
</li>
<li>OS : Testé sur OpenBSD <strong>6.3</strong> =&gt; <strong>6.6</strong></li>
</ul>
<h3 id="installation">Installation</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Ce tutoriel ne documente pas dans les moindres détails les phases
d&rsquo;installation, voire de configuration. Ce n&rsquo;est pas accessible aux nouveaux
utilisateurs d&rsquo;OpenBSD…</p>
<p>Il est <strong>VRAIMENT</strong> nécessaire de faire preuve de réflexion, discernement et
d&rsquo;avoir un minimum de compétences, pour comprendre les liens entre les
différentes briques !</p>
<p>Merci de votre compréhension.</p>
</div>

<h4 id="par-les-paquets">Par les paquets</h4>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>nextcloud</strong>.</p>
<h4 id="par-larchive-officielle">Par l&rsquo;archive officielle</h4>
<p>Par convention, disons que nous déposerons l&rsquo;archive dans le répertoire
<code>/var/www/htdocs/nextcloud</code> - <em>que vous pouvez/devez modifier/adapter à votre besoin</em>…</p>
<pre tabindex="0"><code>:# mkdir /var/www/htdocs/nextcloud
:$ cd /var/www/htdocs/nextcloud
</code></pre><p>Téléchargeons l&rsquo;archive et le fichier de sommes de contrôle sha256 adéquate :</p>
<p><code>:$ ftp https://download.nextcloud.com/server/releases/nextcloud-17.0.1.zip{,.sha256}</code></p>
<p>Puis vérifions que l&rsquo;archive est bien téléchargée :</p>
<pre tabindex="0"><code>:$ sha256 -C nextcloud-*.sha256
(SHA256) nextcloud-17.0.1.zip: OK
</code></pre><p>Si le message est identique, alors l&rsquo;archive téléchargée est bonne.
Nous pouvons donc l&rsquo;utiliser :</p>
<pre tabindex="0"><code>:$ unzip nextcloud*.zip
:# mv nextcloud /var/www/htdocs/
:# chown -R www:daemon /var/www/htdocs/nextcloud
</code></pre><h4 id="php">PHP</h4>
<p>Il est nécessaire d&rsquo;<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

les paquets PHP suivants, tels que : <br>
<strong>php-bz2 php-curl php-gd php-pdo_sqlite php-intl php-zip pecl72-redis redis libmcrypt oniguruma icu4c-wwwdata</strong></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il est possible d&rsquo;installer PHP 7.3 ; faites attention à la version du paquet
<code>pecl7*-redis</code> !</div>

<h5 id="bibliothèque-sodium">Bibliothèque sodium</h5>
<p>Certaines options de Nextcloud nécessitent la gestion de bibliothèque
cryptographique ; il nous faut
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 la <strong>libsodium</strong></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pour PHP 7.x, il est nécessaire de rajouter la bibliothèque <code>pecl7*-libsodium</code>
<em>(où 7* est à remplacer par le numéro de version de PHP-7)</em> - qui n&rsquo;existe plus
dès PHP 7.3, car ce dernier gére correctement la libsodium.</div>

<h5 id="activer-les-extensions-php">Activer les extensions PHP</h5>
<p>Ensuite, il faut activer les différentes extensions :</p>
<pre tabindex="0"><code>:$ cd /etc/php-7.3.sample
:# for i in *; do ln -sf ../php-7.3.sample/$i ../php-7.2/; done
</code></pre><p>Puis, redémarrer le service PHP-FPM.</p>
<h3 id="gestion-du-service-php">Gestion du service PHP</h3>
<p><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer le service</a>

le service PHP-FPM <strong>php73_fpm</strong> !</p>
<h4 id="bases-de-données">Bases de données</h4>
<p>Par défaut, Nextcloud fonctionne avec sqlite ; veillez à ce que le
package nécessaire soit <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installé</a>
 : <br>
<strong>sqlite3 php-pdo_sqlite php-pdo_odbc</strong></p>
<p>Néanmoins Nextcloud fonctionne aussi avec les bases de données MySQL/MariaDB,
PostgreSQL… <br>
à vous de choisir et d&rsquo;installer les paquets correspondants !</p>
<p>Dans tous les cas, il faudra <a href="/fr/sys/openbsd/nextcloud/#activer-les-extensions-php">activer les nouvelles extensions php</a>
et redémarrer le service adhoc.</p>
<h3 id="configuration">Configuration</h3>
<h4 id="avec-nginx">Avec nginx</h4>
<p>La documentation officielle de <a href="https://docs.nextcloud.com/server/stable/admin_manual/installation/nginx.html" rel="external">Nextcloud pour nginx</a>
étant bien faite, je vous laisse la regarder !</p>
<p>Faites simplement attention à bien changer la valeur de <code>root</code> pour qu&rsquo;elle
corresponde à votre racine, ici <code>/var/www/htdocs/nextcloud</code> et à adaptez le
reste à votre besoin.</p>
<p>Retrouvez les règles principales de nginx au-travers de ce
<a href="https://cld.stephane-huc.net/s/qi9fc3sm6aRpHiq" rel="external">document</a>
que je partage ! <br>
Il est bien-sûr nécessaire de l&rsquo;intégrer à votre schéma <code>server</code>…</p>
<h4 id="php-fpm">PHP-FPM</h4>
<p>Il est nécessaire, pour que Nextcloud fonctionne bien, de configurer
votre fichier php-fpm afin d&rsquo;ajouter :</p>
<ul>
<li>
<p><code>allow_url_fopen = on</code></p>
</li>
<li>
<p><code>env[PATH] = /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin</code></p>
</li>
<li>
<p><code>post_max_size = 512M</code></p>
</li>
<li>
<p><code>upload_max_filesize = 512M</code></p>
</li>
<li>
<p>De même, si vous utilisez la directive <code>open_basedir</code>, veillez à autoriser
l&rsquo;accès à <code>/dev/urandom</code>.</p>
</li>
<li>
<p>Veuillez aussi lire les recommandations suivantes : <a href="https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/server_tuning.html#tune-php-fpm" rel="external">Tune PHP-FPM</a> et <a href="https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/server_tuning.html#enable-php-opcache" rel="external">Enable PHP OPcache</a></p>
</li>
</ul>
<p>Redémarrez le service PHP-FPM…</p>
<h4 id="nextcloud">Nextcloud</h4>
<h3 id="chroot-php">Chroot PHP</h3>
<p>Étant donné que PHP est chrooté, la commande <code>occ</code>, ainsi que les jobs
cron échouent.</p>
<p>Lorsque <code>occ</code> est exécuté, vous obtenez au moins ce message d&rsquo;erreur :</p>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            <p>Your data directory is invalid Ensure there is a file called
&ldquo;.ocdata&rdquo; in the root of the data directory.</p>
<p>Cannot create &ldquo;data&rdquo; directory This can usually be fixed by giving the
webserver write access to the root directory. See
<a href="https://docs.nextcloud.com/server/16/go.php?to=admin-dir_permissions" rel="external">https://docs.nextcloud.com/server/16/go.php?to=admin-dir_permissions</a></p>

        </blockquote>
    </figure>
</div>

<p><strong>Résoudre ce problème est simple</strong> : il suffit d&rsquo;éditer le fichier de config
de nextcloud, <code>nextcloud/config/config.php</code> pour modifier la valeur de la
variable <code>datadirectory</code>. <em>(cf : 
<a class="inside" href="/fr/web/nextcloud/nextcloud-php-chroot/" title="Lien interne vers l&#39;article : 'Nextcloud Php Chroot OpenBSD (astuce)'">Nextcloud Php Chroot OpenBSD (astuce)</a>

)</em></p>
<p>Bien sûr, le chemin <code>/data</code> doit correspondre à votre cas, surtout si vous
l&rsquo;avez déplacé hors de la racine <em>nextcloud</em> - ce qui est recommandé !</p>
<p>Ce changement étant fait, vous pouvez utiliser sans soucis la commande <code>occ</code>.</p>
<h3 id="gestion-des-applications">Gestion des applications</h3>
<h4 id="collaboracode">Collabora/CODE</h4>
<p>À quoi sert <a href="https://nextcloud.com/collaboraonline/" rel="external">Collabora</a> CODE ?</p>
<p>À pouvoir éditer les documents bureautique dans Nextcloud directement. <br>
<strong>Malheureusement, ne cherchez pas : cela ne fonctionne pas nativement sur
OpenBSD</strong> !</p>
<h3 id="joujou-dans-la-vm">Joujou dans la VM</h3>
<p>Le moyen : dans une 
<a class="inside" href="/fr/sys/openbsd/vm-debian-stretch/" title="Lien interne vers l&#39;article : ''">VM</a>
 ! :p</p>
<h3 id="deux-méthodes">Deux méthodes</h3>
<p>Il existe deux méthodes pour pouvoir utiliser Collabora CODE :</p>
<ul>
<li>
<p>la méthode facile : au-travers d&rsquo;une image <a href="/fr/sys/openbsd/nextcloud/#par-docker">docker</a> installable
sur Debian</p>
</li>
<li>
<p>une méthode longue mais simple, grâce à ce projet <a href="/fr/sys/openbsd/nextcloud/#par-script-shell-officeonline">officeonline-install.sh</a></p>
</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">De plus, je ne propose des modifications QUE pour nginx !</div>

<h3 id="par-docker">Par Docker</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Je ne vous apprendrais pas à utiliser Docker ! <br>
Et, je ne recommande pas du tout cette possibilité… <br>
si vous avez envie de rajouter une couche de problèmes, libre à vous !</div>

<p>Une fois dans votre VM Debian, il faut installer docker puis l&rsquo;image fournie
par les soins de Collabora.</p>
<pre tabindex="0"><code>:# apt install docker-ce
:$ docker pull collabora/code
</code></pre><p>Ensuite il faut exécuter la commande suivante en l&rsquo;adaptant au nom de domaine
où se trouve votre instance de Nextcloud : <br>
<code>:$ docker run -t -d -p 127.0.0.1:9980:9980 -e 'domain=cloud\\.nextcloud\\.com' --restart always --cap-add MKNOD collabora/code</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Je propose de créer un petit script shell qui permettra toute modification
aisément de la commande au cas où :</p>
<pre tabindex="0"><code>#!/bin/sh
docker run -t -d -p 127.0.0.1:9980:9980 -e &#39;domain=nom-domaine.tld&#39; \--restart always \--cap-add MKNOD collabora/code
</code></pre></div>

<h4 id="iptables">Iptables</h4>
<p>Il est très probable qu&rsquo;il faille modifier <em>iptables</em> tel que, par exemple :</p>
<pre tabindex="0"><code>iptables -A FORWARD -i docker0 -o enp0s3 -j ACCEPT
iptables -A FORWARD -i enps0s3 -o docker0 -j ACCEPT
iptables -A INPUT -i docker0 -j ACCEPT
</code></pre><h4 id="tests-réseaux">Tests réseaux</h4>
<p>Depuis votre machine hôte, normalement il est possible de pinger la VM et de
tester une requête CURL.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ ping -c3 192.168.0.2
</span></span><span style="display:flex;"><span>PING 192.168.0.2 <span style="color:#5bc4bf">(</span>192.168.0.2<span style="color:#5bc4bf">)</span>: <span style="color:#f99b15">56</span> data bytes
</span></span><span style="display:flex;"><span><span style="color:#f99b15">64</span> bytes from 192.168.0.2: <span style="color:#ef6155">icmp_seq</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#ef6155">ttl</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">64</span> <span style="color:#ef6155">time</span><span style="color:#5bc4bf">=</span>0.254 ms
</span></span><span style="display:flex;"><span><span style="color:#f99b15">64</span> bytes from 192.168.0.2: <span style="color:#ef6155">icmp_seq</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> <span style="color:#ef6155">ttl</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">64</span> <span style="color:#ef6155">time</span><span style="color:#5bc4bf">=</span>0.278 ms
</span></span><span style="display:flex;"><span><span style="color:#f99b15">64</span> bytes from 192.168.0.2: <span style="color:#ef6155">icmp_seq</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> <span style="color:#ef6155">ttl</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">64</span> <span style="color:#ef6155">time</span><span style="color:#5bc4bf">=</span>0.301 ms
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>--- 192.168.0.2 ping statistics ---
</span></span><span style="display:flex;"><span><span style="color:#f99b15">3</span> packets transmitted, <span style="color:#f99b15">3</span> packets received, 0.0% packet loss
</span></span><span style="display:flex;"><span>round-trip min/avg/max/std-dev <span style="color:#5bc4bf">=</span> 0.254/0.278/0.301/0.019 ms
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ curl -Iv http://192.168.0.2:9980
</span></span><span style="display:flex;"><span>* Rebuilt URL to: http://192.168.0.2:9980/
</span></span><span style="display:flex;"><span>*   Trying 192.168.0.2...
</span></span><span style="display:flex;"><span>* TCP_NODELAY set
</span></span><span style="display:flex;"><span>* Connected to 192.168.0.2 <span style="color:#5bc4bf">(</span>192.168.0.2<span style="color:#5bc4bf">)</span> port <span style="color:#f99b15">9980</span> <span style="color:#5bc4bf">(</span><span style="color:#776e71">#0)</span>
</span></span><span style="display:flex;"><span>&gt; HEAD / HTTP/1.1
</span></span><span style="display:flex;"><span>&gt; Host: 192.168.0.2:9980
</span></span><span style="display:flex;"><span>&gt; User-Agent: curl/7.61.1
</span></span><span style="display:flex;"><span>&gt; Accept: */*
</span></span><span style="display:flex;"><span>&gt;
</span></span><span style="display:flex;"><span>* Empty reply from server
</span></span><span style="display:flex;"><span>* Connection <span style="color:#776e71">#0 to host 192.168.0.2 left intact</span>
</span></span><span style="display:flex;"><span>curl: <span style="color:#5bc4bf">(</span>52<span style="color:#5bc4bf">)</span> Empty reply from server
</span></span></code></pre></div><p>Si <strong>curl</strong> répond ainsi, c&rsquo;est que cela semble bon !</p>
<p>Maintenant, passons aux <a href="/fr/sys/openbsd/nextcloud/#modifications-nginx">modifications du serveur nginx</a>,
puis à l&rsquo;administration de Nextcloud.</p>
<h5 id="update-docker">Update docker</h5>
<p>Récupère la nouvelle image : <code>$ docker pull collabora/code</code></p>
<p>Arrêt de l&rsquo;image en cours :
<code>:$ docker container ls </code>:$ docker container stop CONTAINER_ID<code>, ou </code>NAMES<code>fonctionne aussi \</code>:$ docker container rm CONTAINER_ID<code>, ou </code>NAMES`</p>
<p>On relance la commande <code>docker run…</code>, vue précédemment ci-dessus !</p>
<h5 id="modification-nginx">Modification nginx</h5>
<p>Les modifications des règles <code>location</code> pour nginx sont fournies dans ce
<a href="https://cld.stephane-huc.net/s/2o6SDdYKQtifCYA" rel="external">document</a>…</p>
<p>Veillez à remplacer les écritures <code>http://localhost</code>, par votre schéma</p>
<ul>
<li>adresse IPv4 de votre VM !</li>
</ul>
<p>Puis relancer le service nginx… et <a href="/fr/sys/openbsd/nextcloud/#modification-nextcloud">administrons</a>
Nextcloud !</p>
<h3 id="par-script-shell-officeonline">Par script shell officeonline</h3>
<p>Il suffit de cloner le dépôt et d&rsquo;exécuter le script shell
<em><a href="https://github.com/husisusi/officeonlin-install.sh" rel="external">officeonline-install.sh</a></em>.</p>
<p>L&rsquo;intérêt de ce script est d&rsquo;installer tout ce qui est nécessaire
afin de se débarrasser des limitations fournies dans le projet Docker de
l&rsquo;entreprise Collabora.</p>
<pre tabindex="0"><code>$ git clone https://github.com/husisusi/officeonlin-install.sh.git
$ cd officeonlin-install.sh
</code></pre>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>ATTENTION, ce script demande de
<a href="https://github.com/husisusi/officeonlin-install.sh#requirements" rel="external">grosses ressources machine</a>
car la phase de compilation et d&rsquo;installation se déroule durant des heures !</p>
<ul>
<li>un minimum de 3.7 Go de RAM</li>
<li>un minimum de 13 Go d&rsquo;espace disque vide…</li>
</ul></div>

<p>Voir <a href="https://help.nextcloud.com/t/howto-install-onlineoffice-on-ubuntu-debian-no-docker-no-limitation/8958" rel="external">le projet sur le forum</a>
d&rsquo;entraide de Nextcloud…</p>
<hr>
<p>Les valeurs actuellement fonctionnelles, sur une Debian Stretch, du fichier de
configuration <code>officeonline-install.cfg</code> sont
<a href="https://github.com/husisusi/officeonlin-install.sh/issues/155#issuecomment-451502770" rel="external">celles-ci</a>: \</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">set_online_regex</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;collabora/collabora-online-4$&#39; #CODE 4 Branch</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">lool_src_commit</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;173510fdbf6f52d1d6288b809c8d14bc630afd20&#39; #CODE-4-RC2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">set_core_regex</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;cp-6.0$&#39; #LibO 6.0.x</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION, ces valeurs peuvent changer très rapidement… veuillez toujours
vérifier soit sur le forum d&rsquo;entraide de Nextcloud, soit sur le projet
d&rsquo;OfficeOnline.</div>

<p>Pensez à modifier aussi la valeur de <code>allowed_domains</code> en début de fichier, en
faisant correspondre avec le nom de domaine qui gère votre nextcloud ou le
service collabora s&rsquo;il est sur un serveur distinct.</p>
<p>Une fois le fichier de configuration modifié, exécutez la commande suivante : <br>
<code>:# officeonline-install.sh -c officeonline-install.cfg</code></p>
<p>Puis, patientez le temps de la phase de compilation et d&rsquo;installation…</p>
<p>Si à la fin, vous avez un message ressemblant au suivant, alors c&rsquo;est bon :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### loolwsd is running. Enjoy!!! Service will be stopped after this ###</span>
</span></span><span style="display:flex;"><span>COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
</span></span><span style="display:flex;"><span>loolwsd <span style="color:#f99b15">19422</span> lool   17u  IPv6 <span style="color:#f99b15">320498</span>      0t0  TCP *:9980 <span style="color:#5bc4bf">(</span>LISTEN<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span></code></pre></div><p>Redémarrez votre VM, vérifiez votre config nginx, puis modifiez votre
configuration de <a href="/fr/sys/openbsd/nextcloud/#modification-nextcloud">Nextcloud</a>…</p>
<hr>
<h3 id="modification-nextcloud">Modification Nextcloud</h3>
<p>Se connecter à l&rsquo;interface web de Nextcloud en tant qu&rsquo;administrateur,
puis dans le menu <em>Applications</em> &gt; Section <em>Office &amp;
text</em>/<em>Bureautique</em> et installer l&rsquo;application <em>Collabora Office</em>.</p>
<p>Ensuite, choisir le menu <em>Settings</em>/<em>Paramètres</em> &gt; <em>Collabora Online</em>
et spécifier le nom du domaine sur lequel fonctionne la VM Debian ; il
doit correspondre <strong>ABSOLUMENT</strong> selon votre choix de configuration,
soit :</p>
<ul>
<li>à la mention <code>domain</code> que vous avez rempli lors de l&rsquo;exécution du containeur
Docker…</li>
<li>à la mention <code>allowed_domains</code> remplie pour la configuration du script
<code>officeonline</code>…</li>
</ul>
<hr>
<h4 id="talk">Talk</h4>
<p>Pour pouvoir communiquer par vidéo et/ou par chat, il faut installer l&rsquo;application
officielle <em>Talk</em> avec un compte administrateur depuis l&rsquo;interface d&rsquo;administration
de Nextcloud.</p>
<p>Ensuite, il faut configurer un serveur <a href="/fr/sys/openbsd/nextcloud/#turn">Turn</a></p>
<p>Pour finir, chaque utilisateur inscrit de votre nuage informatique pourra
communiquer avec un autre, soit à partir de l&rsquo;application <em>Nextcloud Talk</em> sur
un smartphone, soit à partir de l&rsquo;interface web de Nextcloud une fois connecté.</p>
<hr>
<h4 id="turn">Turn</h4>
<p>L&rsquo;installation d&rsquo;un serveur STUN/TURN, pour que l&rsquo;application <strong><a href="/fr/sys/openbsd/nextcloud/#talk">Talk</a></strong>
fonctionne, est expliqué dans mon tutoriel 
<a class="inside" href="/fr/sys/openbsd/turnserver/" title="Lien interne vers l&#39;article : 'OpenBSD : Service TURN'">OpenBSD : Service TURN</a>

.</p>
<p>Ensuite, il est nécessaire de paramétrer Nextcloud. Connectez-vous à son
interface en tant qu&rsquo;administrateur, puis choisissez le menu
<em>Settings/Paramètres</em> &gt; <em>Talk/Discussion</em>.</p>
<p>Voici en image l&rsquo;interface :
<figure>
    <a href="/images/openbsd/nextcloud-stun.png" title="Nextcloud : Serveurs STUN">
    <picture>
        
        <source srcset="/images/openbsd/nextcloud-stun_hu_97519c83e7baf600.webp" type="image/webp">
        
        <img alt="Nextcloud : Serveurs STUN" height="150" loading="lazy" src="/images/openbsd/nextcloud-stun_hu_36f73d3fea931fdd.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Nextcloud : Serveurs STUN</figcaption>
</figure></p>
<p>Écrivez dans les champs :</p>
<ul>
<li>
<p><code>Serveur STUN</code>, écrivez : <code>nom-domaine.tld:3478</code></p>
</li>
<li>
<p><code>Serveur TURN</code>, écrivez : <code>nom-domaine.tld:5349</code>, puis le champ suivant le
secret d&rsquo;authentification que vous avez configuré pour l&rsquo;option <code>static-auth-secret</code>
dans le fichier de configuration du serveur Turn. Puis changez si besoin
les protocoles utilisés.</p>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Bien-sûr, l&rsquo;inscription <em>nom-domaine.tld</em> est à remplacer par votre véritable
nom de domaine où le serveur Turn est installé ! <br>
Quant au numéro de port du serveur STUN, et du serveur TURN, mettez ceux
configurés dans le fichier du serveur Turn !</div>

<p>Une fois configuré, il n&rsquo;y a plus qu&rsquo;à utiliser l&rsquo;application <em>Nextcloud <a href="/fr/sys/openbsd/nextcloud/#talk">Talk</a></em>
soit sur votre smartphone, soit à-partir de l&rsquo;interface web de Nextcloud depuis
votre compte.</p>
<h2 id="remerciements">Remerciements</h2>
<p>Source:</p>
<ul>
<li><a href="https://nextcloud.com/collaboraonline/" rel="external">https://nextcloud.com/collaboraonline/</a></li>
<li><a href="https://www.collaboraoffice.com/code/nginx-reverse-proxy/" rel="external">https://www.collaboraoffice.com/code/nginx-reverse-proxy/</a></li>
<li><a href="https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794" rel="external">https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794</a></li>
<li><a href="https://www.apb-informatique.fr/nextcloud-installation-de-lapplication-collabora-online/" rel="external">https://www.apb-informatique.fr/nextcloud-installation-de-lapplication-collabora-online/</a></li>
</ul>
<hr>
<p><em><strong>Enjoy-IT! <br>
Enjoy-ID!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mettre en place un service de cloud avec Nextcloud distribué par le serveur web nginx sur OpenBSD]]></summary>
        <published>2018-12-25T14:25:01+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1405c363-4818-52d5-77cd-2919486d50e8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/turnserver/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Service TURN</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="TURN" scheme="http://doc.huc.fr.eu.org/fr/tags/turn/" />
        <category term="VoIP" scheme="http://doc.huc.fr.eu.org/fr/tags/voip/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un serveur TURN est un serveur de 











































































































<span lang="en">VoIP <em>(Voices and videos over IP)</em></span>



 - un serveur de trafic qui
passe sur les réseaux 



























































<span lang="en">NAT <em>(Network Address Translation)</em></span>



















































 et au-travers des passerelles.</p>
<ul>
<li>Site web : <a href="https://github.com/coturn/coturn" rel="external">https://github.com/coturn/coturn</a></li>
<li>Version installée : 4.5.0.7p0</li>
<li>OS : OpenBSD 6.4</li>
</ul>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>turnserver</strong> !</p>
<p>Un utilisateur <code>_turnserver</code> sans droit système est créé !</p>
<h2 id="configuration">Configuration</h2>
<h3 id="fichier-de-configuration-etcturnserverconf">Fichier de configuration <code>/etc/turnserver.conf</code></h3>
<p>Il faut décommenter ou remplir les options suivantes :</p>
<ul>
<li><code>fingerprint</code></li>
<li><code>lt-cred-mech</code></li>
<li><code>use-auth-secret</code></li>
<li><code>static-auth-secret</code> - pour <a href="/fr/sys/openbsd/turnserver/#secret-d-authentification">générer un secret d&rsquo;authentification</a>…</li>
<li><code>realm</code> - écrire le nom de domaine ou sous-domaine</li>
<li><code>total-quota</code> - paramétrer la à la valeur de <code>100</code></li>
<li><code>bps-capacity</code> - valeur de <code>0</code></li>
<li><code>stale-nonce</code></li>
<li><code>no-loopback-peers</code></li>
<li><code>no-multicast-peers</code></li>
</ul>
<h3 id="http-ou-https">HTTP ou HTTPS</h3>
<p>Quelques options à modifier pour avoir une configuration fonctionnelle :</p>
<ul>
<li>
<p>Si 































































































<span lang="en">TLS <em>(Transport Layer Secure)</em></span>















/































<span lang="en">HTTPS <em>(HyperText Transfer Protocol Secure)</em></span>















































































: <code>tls-listening-port</code> - la valeur
par défaut du port est <code>5349</code></p>
</li>
<li>
<p>Autrement : <code>listening-port</code> - la valeur par défaut du port est <code>3478</code></p>
</li>
</ul>
<p>Si vous utilisez 
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































, il faut en plus paramétrer ces options :</p>
<ul>
<li>
<p><code>cert</code> - chemin vers le certificat 
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































 du serveur</p>
</li>
<li>
<p><code>pkey</code> - chemin vers la clé privée liée au certificat HTTPS du serveur</p>
</li>
<li>
<p><code>cipherlist</code> - il est fortement recommandé de modifier cette option à
l&rsquo;identique de la configuration de votre serveur web, si vous en avez un
actif sur le même serveur. <br>
Voici les valeurs minimales : <code>ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5</code></p>
</li>
<li>
<p>il est possible d&rsquo;exclure les versions suivantes des protocoles 
































































































<abbr lang="en" title="Transport Layer Secure">TLS</abbr>
















en utilisant les options suivantes : <code>no-tlsv1</code> et <code>no-tlsv1_1</code></p>
</li>
<li>
<p>il est possible de <a href="/fr/sys/openbsd/turnserver/#fichier-diffie-hellman">configurer un fichier Diffie-Hellman</a>
c&rsquo;est l&rsquo;option <code>dh-file</code> - <em>n&rsquo;utilisez pas le même que celui de votre
serveur web ; générez-en exprès rien que pour ce service !</em></p>
</li>
</ul>
<h3 id="cli">CLI</h3>
<p>Par défaut, l&rsquo;interface d&rsquo;administration en ligne de commande est activée !</p>
<p>Pour la désactiver, il faut décommenter l&rsquo;option <code>no-cli</code>…</p>
<p>Sinon, décommentez les options suivantes pour ajouter un peu de sécurité
dessus :</p>
<ul>
<li>
<p><code>cli-ip</code> - la valeur par défaut est <code>127.0.0.1</code>, sauf à raison contraire, laissez-la telle quelle.</p>
</li>
<li>
<p><code>cli-port</code> - la valeur par défaut est <code>5766</code>.</p>
</li>
<li>
<p><code>cli-password</code> - si l&rsquo;option reste commentée, il n&rsquo;y aura pas de mot de passe -
<a href="/fr/sys/openbsd/turnserver/#turnadmin">générez un nouveau mot de passe</a>avec la commande <code>turnadmin</code> et
copiez-le…</p>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Par défaut, l&rsquo;interface CLI est accessible sur le réseau en clair. <br>
Pour administrer de manière plus sécurisée, ouvrez une session ssh sur votre
machine, puis administrez votre serveur turn… ;)</div>

<h3 id="bases-de-données">Bases de données</h3>
<p>Par défaut, SQLite est utilisée, et les données sont enregistrées dans
<code>/var/db/turndb</code> - là, encore, sous OpenBSD, il est nécessaire que l&rsquo;utilisateur
<code>_turnserver</code> ait les droits sur ledit fichier.</p>
<p>Pour les bases de données, MySQL/MariaDB, PostgreSQL, Mongo, Redis,
veuillez lire le fichier <a href="https://github.com/coturn/coturn/blob/master/INSTALL" rel="external">INSTALL</a> !</p>
<h3 id="logs">Logs</h3>
<p>Il est possible de gérer les journaux en modifiant/activant les options
suivantes :</p>
<ul>
<li>
<p><code>no-stdout-log</code> - empêcher que les journaux soient publiés sur la sortie
standard</p>
</li>
<li>
<p><code>syslog</code> - rediriger les sorties vers le journal syslog</p>
</li>
<li>
<p><code>simple-log</code></p>
</li>
<li>
<p><code>log-file</code> - donnez-lui le chemin absolu vers le nom de fichier dans lequel
vous désirez que les journaux soient écrits.</p>
</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION, il est nécessaire que l&rsquo;utilisateur lié au service puisse lire le
fichier journal. Il semble qu&rsquo;il ne peut être écrit que dans <code>/var/tmp/turn.log</code>.</div>

<h3 id="secret-dauthentification">Secret d&rsquo;authentification</h3>
<p>Pour générer un secret d&rsquo;authentification, il suffit de se servir de la
commande <em>openssl</em>, tel que : <br>
<code>:$ openssl rand -hex 32</code></p>
<h3 id="fichier-diffie-hellman">Fichier Diffie-Hellman</h3>
<p>Là, aussi, <em>openssl</em> sera notre secours, tel que : <br>
<code>$ openssl dhparam -out dhparam_4096.pem 4096</code> <br>
ce qui nous générera un fichier de 4096 bits.</p>
<h3 id="turnadmin">Turnadmin</h3>
<p>Pour générer un mot de passe, il faut utiliser l&rsquo;option <code>-P</code>
<em>(ou son équivalent : <code>--generate-encrypted-password*</code>)</em>
alliée de l&rsquo;option <code>-p</code> <em>(ou son équivalent : <code>--password</code>)</em>.</p>
<ul>
<li>pour l&rsquo;option <code>cli-password</code> : <code>:$ turnadmin -P -p cli-password</code></li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<h3 id="warning-cannot-find-private-key-file">WARNING: cannot find private key file</h3>
<p>Les journaux indiquent que le fichier relatif à la clé privée du certificat


























































































<span lang="en">SSL <em>(Secure Sockets Layer)</em></span>





















/
































<abbr lang="en" title="HyperText Transfer Protocol Secure">HTTPS</abbr>















































































 ne peut être lu, tel que :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">Dec 19 09:08:17 srvr turnserver: 0: WARNING: cannot find private key file: /etc/ssl/acme/private/mydomain.net.privkey.pem (1)
Dec 19 09:08:17 srvr turnserver: 0: WARNING: cannot start TLS and DTLS listeners because private key file is not set properly
</code></pre><p>En effet, lors de la génération par le client acme natif sous OpenBSD, les droits
sur ledit fichier appartiennent en lecture seule à <code>root:wheel</code> - or, le serveur
fonctionne avec les droits de l&rsquo;utilisateur <code>_turnserver</code>, il ne peut donc pas
y accéder… <br>
<em>(bien sûr, je n&rsquo;ai pas abordé la génération de certificats 
































































































<abbr lang="en" title="Transport Layer Secure">TLS</abbr>
















avec Lets&rsquo;Encrypt… voici un exemple d&rsquo;explication pour le <a href="https://ybad.name/ah/doku.php/4-httpd/ssl" rel="external">client acme sous OpenBSD</a>)</em></p>
<ul>
<li>
<p>Une des manières est de copier la clé privée de la mettre dans un répertoire
où seul l&rsquo;utilisateur <code>_turnserver</code> aura accès avec des droits en lecture
seule, et sur le répertoire et sur le fichier de clé privée copié. <br>
Une fois fait, indiquez à l&rsquo;option <code>pvkey</code> le nouveau chemin.</p>
</li>
<li>
<p>L&rsquo;autre serait de créer un groupe sans droits systèmes, d&rsquo;y ajouter l&rsquo;utilisateur
<code>_turnserver</code> et d&rsquo;attribuer les droits 0440 sur le fichier original de la
clé privée.</p>
</li>
</ul>
<p><em>Personnellement, je n&rsquo;aime ni l&rsquo;une, ni l&rsquo;autre de ces deux solutions</em>… <br>
mais je ne peux proposer mieux !</p>
<h2 id="démarrer-le-service">Démarrer le service</h2>
<p>Une fois le fichier configuré, il ne vous reste plus qu&rsquo;à activer le
service et le démarrer à l&rsquo;aide de l&rsquo;outil <code>rcctl</code> : <br>
<code>:# rcctl start turnserver</code></p>
<h2 id="règles-pf">Règles PF</h2>
<p>La configuration des règles du pare-feu PF est un peu plus délicate. Gardez à
l&rsquo;esprit que ce sont des <em>règles à modifier selon vos nécessités</em> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">host</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;ipv4 address server&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">host6</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;ipv6 address server&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">cli_port</span>  <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;5766&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">turn_port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;3478&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">turn_tls_port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;5349&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># empêcher les connexions sur l&#39;interface CLI</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block drop in quick log on egress proto { tcp udp } from any to egress port $cli_port label &#34;turn: unwanted connexion to cli&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick log on egress proto { tcp udp } from any to { $host $host6 } port { $turn_port $turn_tls_port } flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><p>Il est très intéressant de déclarer une table abuse et de modifier la règle qui
bloque la connexion à l&rsquo;interface CLI afin que les 


































<span lang="en">IP <em>(Internet Protocol)</em></span>












































































 correspondantes
soient enregistrées dans la table abuse. <br>
Veillez à créer une tâche cron pour purger régulièrement ladite table ;)</p>
<h2 id="remerciements">Remerciements</h2>
<p>Source : <a href="https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794" rel="external">https://help.nextcloud.com/t/howto-setup-nextcloud-talk-with-turn-server/30794</a></p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Mettre en place un serveur TURN sous OpenBSD]]></summary>
        <published>2018-12-24T21:28:03+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:00eb0105-a56e-34e4-4337-1d84210af4d1</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/php/sitemap-gz/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP5|7 : un fichier sitemap.xml, ou sitemap.xml.gz</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP5" scheme="http://doc.huc.fr.eu.org/fr/tags/php5/" />
        <category term="PHP7" scheme="http://doc.huc.fr.eu.org/fr/tags/php7/" />
        <category term="sitemap" scheme="http://doc.huc.fr.eu.org/fr/tags/sitemap/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou comment créer un fichier <strong><a href="https://www.sitemaps.org/fr/" rel="external">sitemap.xml</a></strong> - ou sa version compressée
<strong>sitemap.xml.gz</strong> en PHP.</p>
<h2 id="sitemapxml-basique">Sitemap.xml basique</h2>
<p>Voyons comment écrire en PHP un sitemap.xml très basique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### créons les constantes utiles
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du protocole utilisé : scheme
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> ( <span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTPS&#39;</span>]) ) <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;http&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;https&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du nom d&#39;hôte et écriture de la base URL
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;HOST&#39;</span>, <span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTP_HOST&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;BASE&#39;</span>, <span style="color:#06b6ef">SCHEME</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;://&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">HOST</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du chemin absolu, réel du script
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;ROOT&#39;</span>, <span style="color:#06b6ef">realpath</span>(<span style="color:#06b6ef">getenv</span>(<span style="color:#48b685">&#39;DOCUMENT_ROOT&#39;</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture de l&#39;entête XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;urlset xmlns=&#34;http://www.google.com/schemas/sitemap/0.9&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xsi:schemaLocation=&#34;http://www.google.com/schemas/sitemap/0.9
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> http://www.google.com/schemas/sitemap/0.9/sitemap.xsd&#34;&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on récupère les informations du fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$file_mtime</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#06b6ef">filemtime</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/index.php&#39;</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture du flux, relatif au fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;loc&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/loc&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;lastmod&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$file_mtime</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/lastmod&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;priority&gt;1&lt;/priority&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture finale du flux XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;/urlset&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on envoie le flux avec le bon entête et le bon encodage
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/xml; charset=utf-8&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">echo</span> <span style="color:#ef6155">$flux</span>;
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Bien-sûr l&rsquo;écriture du fichier <code>sitemap.xml</code> est basique, non compressé,
et ne sert - <em>dans ce cas</em> - qu&rsquo;à indexer le fichier <code>index.php</code> - <em>cas peu utile,
avouons-le</em> !</p>
<h2 id="parcours-de-répertoire">Parcours de répertoire</h2>
<p>Maintenant, admettons que nous avons un répertoire &lsquo;outils&rsquo;, dans lequel
nous avons différents scripts PHP que nous souhaitons indexer, eux aussi ;)</p>
<p>Pour cela, nous allons utiliser les Itérateurs par parcourir le répertoire,
puis récupérer les informations de fichier par le biais de la classe SPL !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># créons un tableau...
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$folders</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">array</span> (<span style="color:#48b685">&#39;tools&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># parcours du tableau et exécutions d&#39;instructions relatives...
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$folders</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">switch</span>(<span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#39;tools&#39;</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$pattern</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;/^.+\.php$/i&#39;</span>; <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># Utilisons les fonctions Iterator pour parcourir le bon répertoire depuis sa racine absolue.
</span></span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Directory</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveDirectoryIterator</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Iterator</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveIteratorIterator</span>(<span style="color:#ef6155">$Directory</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$dirs</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RegexIterator</span>(<span style="color:#ef6155">$Iterator</span>, <span style="color:#ef6155">$pattern</span>, <span style="color:#06b6ef">RecursiveRegexIterator</span><span style="color:#5bc4bf">::</span><span style="color:#06b6ef">GET_MATCH</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># parcours de l&#39;objet Iterateur, pour écrire le flux XML nécessaire,
</span></span></span><span style="display:flex;"><span>    <span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$dirs</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$dir</span> <span style="color:#5bc4bf">=&gt;</span> <span style="color:#ef6155">$dirs</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$info</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">SplFileInfo</span>(<span style="color:#ef6155">$dir</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># construction de l&#39;URL visible
</span></span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getBasename</span>()<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># récupération de la date de dernière modification du fichier - cf, l&#39;argument &#39;&#39;c&#39;&#39; permet de restituer directement la date au bon format attendu
</span></span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getCTime</span>())<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">### l&#39;ancienne méthode donnerait ce code PHP
</span></span></span><span style="display:flex;"><span>        <span style="color:#776e71">#$flux .= &#34;      &lt;loc&gt;&#34;.BASE.&#39;/&#39;.$name.&#39;/&#39;.basename($dir).&#34;&lt;/loc&gt;&#34;.&#34;\n&#34;;
</span></span></span><span style="display:flex;"><span>        <span style="color:#776e71">#$flux .= &#34;      &lt;lastmod&gt;&#34;.date (&#34;c&#34;, filemtime($dir)).&#34;&lt;/lastmod&gt;&#34;.&#34;\n&#34;;
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Bien-sûr, ce code PHP de parcours de dossier et de restitution d&rsquo;informations
fichiers, envoyé dans le flux XML nécessaire, est à intégrer après le code
relatif au fichier index et avant le code de fermeture du flux XML.</p>
<h2 id="compression-du-sitemapxml">Compression du sitemap.xml</h2>
<p>Maintenant, voyons comment compresser de manière simple et rapide le flux
XML pour créer un fichier <strong>sitemap.xml.gz</strong> nécessaire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on prend le flux XML dans son ensemble pour l&#39;encoder en gz
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$gzdata</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">gzencode</span>(<span style="color:#ef6155">$flux</span>, <span style="color:#f99b15">9</span>);
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Ensuite pour envoyer les données, utilisons les bons entêtes, puis affichons le flux encodé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># déclaration des entêtes nécessaires
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/x-gzip&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Encoding: gzip&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Disposition: attachment; filename=sitemap.xml.gz&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#776e71"># affichage du flux encodé - et non pas du flux normal !!!
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">echo</span> <span style="color:#ef6155">$gzdata</span>;
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><h2 id="tldr">TL;DR</h2>
<p>Voici la version finale du code PHP pour créer dynamiquement un fichier
<strong>sitemap.xml</strong>, et sa version compressée <strong>sitemap.xml.gz</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### les constantes utiles
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> ( <span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTPS&#39;</span>]) ) <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;http&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;https&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;HOST&#39;</span>, <span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTP_HOST&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;BASE&#39;</span>, <span style="color:#06b6ef">SCHEME</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;://&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">HOST</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;ROOT&#39;</span>, <span style="color:#06b6ef">realpath</span>(<span style="color:#06b6ef">getenv</span>(<span style="color:#48b685">&#39;DOCUMENT_ROOT&#39;</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture de l&#39;entête XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;urlset xmlns=&#34;http://www.google.com/schemas/sitemap/0.9&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xsi:schemaLocation=&#34;http://www.google.com/schemas/sitemap/0.9
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> http://www.google.com/schemas/sitemap/0.9/sitemap.xsd&#34;&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on récupère les informations du fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$file_mtime</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#06b6ef">filemtime</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/index.php&#39;</span>));
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;loc&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/loc&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;lastmod&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$file_mtime</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/lastmod&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;priority&gt;1&lt;/priority&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gestion du répertoire &#39;outils&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$folders</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">array</span> (<span style="color:#48b685">&#39;tools&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$folders</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">switch</span>(<span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#39;tools&#39;</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$pattern</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;/^.+\.php$/i&#39;</span>; <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Directory</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveDirectoryIterator</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Iterator</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveIteratorIterator</span>(<span style="color:#ef6155">$Directory</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$dirs</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RegexIterator</span>(<span style="color:#ef6155">$Iterator</span>, <span style="color:#ef6155">$pattern</span>, <span style="color:#06b6ef">RecursiveRegexIterator</span><span style="color:#5bc4bf">::</span><span style="color:#06b6ef">GET_MATCH</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$dirs</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$dir</span> <span style="color:#5bc4bf">=&gt;</span> <span style="color:#ef6155">$dirs</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$info</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">SplFileInfo</span>(<span style="color:#ef6155">$dir</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getBasename</span>()<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getCTime</span>())<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;/urlset&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># création du flux encodé
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$gzdata</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">gzencode</span>(<span style="color:#ef6155">$flux</span>, <span style="color:#f99b15">9</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># envoi du flux
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span>(<span style="color:#5bc4bf">!</span><span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$gzdata</span>)) {
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/x-gzip&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Encoding: gzip&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Disposition: attachment; filename=sitemap.xml.gz&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">echo</span> <span style="color:#ef6155">$gzdata</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/xml; charset=utf-8&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">echo</span> <span style="color:#ef6155">$flux</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Et, voilà ! :D</p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Générer un fichier sitemap et sa version compressée en PHP 5 et 7]]></summary>
        <published>2018-11-13T19:10:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a905fee1-4a48-5aec-d7ee-c3f277e0391a</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/sitemap-gz/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP5|7 : un fichier sitemap.xml, ou sitemap.xml.gz</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP5" scheme="http://doc.huc.fr.eu.org/fr/tags/php5/" />
        <category term="PHP7" scheme="http://doc.huc.fr.eu.org/fr/tags/php7/" />
        <category term="sitemap" scheme="http://doc.huc.fr.eu.org/fr/tags/sitemap/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou comment créer un fichier <strong><a href="https://www.sitemaps.org/fr/" rel="external">sitemap.xml</a></strong> - ou sa version compressée
<strong>sitemap.xml.gz</strong> en PHP.</p>
<h2 id="sitemapxml-basique">Sitemap.xml basique</h2>
<p>Voyons comment écrire en PHP un sitemap.xml très basique :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### créons les constantes utiles
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du protocole utilisé : scheme
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> ( <span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTPS&#39;</span>]) ) <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;http&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;https&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du nom d&#39;hôte et écriture de la base URL
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;HOST&#39;</span>, <span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTP_HOST&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;BASE&#39;</span>, <span style="color:#06b6ef">SCHEME</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;://&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">HOST</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># détection du chemin absolu, réel du script
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;ROOT&#39;</span>, <span style="color:#06b6ef">realpath</span>(<span style="color:#06b6ef">getenv</span>(<span style="color:#48b685">&#39;DOCUMENT_ROOT&#39;</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture de l&#39;entête XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;urlset xmlns=&#34;http://www.google.com/schemas/sitemap/0.9&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xsi:schemaLocation=&#34;http://www.google.com/schemas/sitemap/0.9
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> http://www.google.com/schemas/sitemap/0.9/sitemap.xsd&#34;&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on récupère les informations du fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$file_mtime</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#06b6ef">filemtime</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/index.php&#39;</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture du flux, relatif au fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;loc&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/loc&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;lastmod&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$file_mtime</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/lastmod&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;priority&gt;1&lt;/priority&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture finale du flux XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;/urlset&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on envoie le flux avec le bon entête et le bon encodage
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/xml; charset=utf-8&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">echo</span> <span style="color:#ef6155">$flux</span>;
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Bien-sûr l&rsquo;écriture du fichier <code>sitemap.xml</code> est basique, non compressé,
et ne sert - <em>dans ce cas</em> - qu&rsquo;à indexer le fichier <code>index.php</code> - <em>cas peu utile,
avouons-le</em> !</p>
<h2 id="parcours-de-répertoire">Parcours de répertoire</h2>
<p>Maintenant, admettons que nous avons un répertoire &lsquo;outils&rsquo;, dans lequel
nous avons différents scripts PHP que nous souhaitons indexer, eux aussi ;)</p>
<p>Pour cela, nous allons utiliser les Itérateurs par parcourir le répertoire,
puis récupérer les informations de fichier par le biais de la classe SPL !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># créons un tableau...
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$folders</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">array</span> (<span style="color:#48b685">&#39;tools&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># parcours du tableau et exécutions d&#39;instructions relatives...
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$folders</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">switch</span>(<span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#39;tools&#39;</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$pattern</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;/^.+\.php$/i&#39;</span>; <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># Utilisons les fonctions Iterator pour parcourir le bon répertoire depuis sa racine absolue.
</span></span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Directory</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveDirectoryIterator</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Iterator</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveIteratorIterator</span>(<span style="color:#ef6155">$Directory</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$dirs</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RegexIterator</span>(<span style="color:#ef6155">$Iterator</span>, <span style="color:#ef6155">$pattern</span>, <span style="color:#06b6ef">RecursiveRegexIterator</span><span style="color:#5bc4bf">::</span><span style="color:#06b6ef">GET_MATCH</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># parcours de l&#39;objet Iterateur, pour écrire le flux XML nécessaire,
</span></span></span><span style="display:flex;"><span>    <span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$dirs</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$dir</span> <span style="color:#5bc4bf">=&gt;</span> <span style="color:#ef6155">$dirs</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$info</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">SplFileInfo</span>(<span style="color:#ef6155">$dir</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># construction de l&#39;URL visible
</span></span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getBasename</span>()<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># récupération de la date de dernière modification du fichier - cf, l&#39;argument &#39;&#39;c&#39;&#39; permet de restituer directement la date au bon format attendu
</span></span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getCTime</span>())<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#776e71">### l&#39;ancienne méthode donnerait ce code PHP
</span></span></span><span style="display:flex;"><span>        <span style="color:#776e71">#$flux .= &#34;      &lt;loc&gt;&#34;.BASE.&#39;/&#39;.$name.&#39;/&#39;.basename($dir).&#34;&lt;/loc&gt;&#34;.&#34;\n&#34;;
</span></span></span><span style="display:flex;"><span>        <span style="color:#776e71">#$flux .= &#34;      &lt;lastmod&gt;&#34;.date (&#34;c&#34;, filemtime($dir)).&#34;&lt;/lastmod&gt;&#34;.&#34;\n&#34;;
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Bien-sûr, ce code PHP de parcours de dossier et de restitution d&rsquo;informations
fichiers, envoyé dans le flux XML nécessaire, est à intégrer après le code
relatif au fichier index et avant le code de fermeture du flux XML.</p>
<h2 id="compression-du-sitemapxml">Compression du sitemap.xml</h2>
<p>Maintenant, voyons comment compresser de manière simple et rapide le flux
XML pour créer un fichier <strong>sitemap.xml.gz</strong> nécessaire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on prend le flux XML dans son ensemble pour l&#39;encoder en gz
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$gzdata</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">gzencode</span>(<span style="color:#ef6155">$flux</span>, <span style="color:#f99b15">9</span>);
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Ensuite pour envoyer les données, utilisons les bons entêtes, puis affichons le
flux encodé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># déclaration des entêtes nécessaires
</span></span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/x-gzip&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Encoding: gzip&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Disposition: attachment; filename=sitemap.xml.gz&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#776e71"># affichage du flux encodé - et non pas du flux normal !!!
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">echo</span> <span style="color:#ef6155">$gzdata</span>;
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><h2 id="tldr">TL;DR</h2>
<p>Voici la version finale du code PHP pour créer dynamiquement un fichier
<strong>sitemap.xml</strong>, et sa version compressée <strong>sitemap.xml.gz</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### les constantes utiles
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> ( <span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTPS&#39;</span>]) ) <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;http&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> <span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;SCHEME&#39;</span>, <span style="color:#48b685">&#39;https&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;HOST&#39;</span>, <span style="color:#ef6155">$_SERVER</span>[<span style="color:#48b685">&#39;HTTP_HOST&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;BASE&#39;</span>, <span style="color:#06b6ef">SCHEME</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;://&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">HOST</span>);
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">define</span>(<span style="color:#48b685">&#39;ROOT&#39;</span>, <span style="color:#06b6ef">realpath</span>(<span style="color:#06b6ef">getenv</span>(<span style="color:#48b685">&#39;DOCUMENT_ROOT&#39;</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># écriture de l&#39;entête XML
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;urlset xmlns=&#34;http://www.google.com/schemas/sitemap/0.9&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> xsi:schemaLocation=&#34;http://www.google.com/schemas/sitemap/0.9
</span></span></span><span style="display:flex;"><span><span style="color:#48b685"> http://www.google.com/schemas/sitemap/0.9/sitemap.xsd&#34;&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on récupère les informations du fichier index
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$file_mtime</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#06b6ef">filemtime</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/index.php&#39;</span>));
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;loc&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/loc&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;lastmod&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$file_mtime</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;&lt;/lastmod&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        &lt;priority&gt;1&lt;/priority&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gestion du répertoire &#39;outils&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$folders</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">array</span> (<span style="color:#48b685">&#39;tools&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$folders</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">switch</span>(<span style="color:#ef6155">$name</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">case</span> <span style="color:#48b685">&#39;tools&#39;</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$pattern</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#39;/^.+\.php$/i&#39;</span>; <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Directory</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveDirectoryIterator</span>(<span style="color:#06b6ef">ROOT</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$Iterator</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RecursiveIteratorIterator</span>(<span style="color:#ef6155">$Directory</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$dirs</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">RegexIterator</span>(<span style="color:#ef6155">$Iterator</span>, <span style="color:#ef6155">$pattern</span>, <span style="color:#06b6ef">RecursiveRegexIterator</span><span style="color:#5bc4bf">::</span><span style="color:#06b6ef">GET_MATCH</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">foreach</span>(<span style="color:#ef6155">$dirs</span> <span style="color:#815ba4">as</span> <span style="color:#ef6155">$dir</span> <span style="color:#5bc4bf">=&gt;</span> <span style="color:#ef6155">$dirs</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$info</span> <span style="color:#5bc4bf">=</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">SplFileInfo</span>(<span style="color:#ef6155">$dir</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">BASE</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$name</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#39;/&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getBasename</span>()<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/loc&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#34;      &lt;lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#06b6ef">date</span> (<span style="color:#48b685">&#34;c&#34;</span>, <span style="color:#ef6155">$info</span><span style="color:#5bc4bf">-&gt;</span><span style="color:#06b6ef">getCTime</span>())<span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;&lt;/lastmod&gt;&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;  &lt;/url&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$flux</span> <span style="color:#5bc4bf">.=</span> <span style="color:#48b685">&#39;&lt;/urlset&gt;&#39;</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># création du flux encodé
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$gzdata</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">gzencode</span>(<span style="color:#ef6155">$flux</span>, <span style="color:#f99b15">9</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># envoi du flux
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span>(<span style="color:#5bc4bf">!</span><span style="color:#815ba4">empty</span>(<span style="color:#ef6155">$gzdata</span>)) {
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/x-gzip&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Encoding: gzip&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Disposition: attachment; filename=sitemap.xml.gz&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">echo</span> <span style="color:#ef6155">$gzdata</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">header</span>(<span style="color:#48b685">&#34;Content-Type: application/xml; charset=utf-8&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">echo</span> <span style="color:#ef6155">$flux</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p>Et, voilà ! :D</p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Générer un fichier sitemap et sa version compressée en PHP 5 et 7]]></summary>
        <published>2018-11-13T19:10:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f128f33e-31fc-dc4d-1ca7-78222bc0bb83</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/smtpd-config-auth/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Configurer smtpd.conf pour l&#39;authentification (depuis OpenBSD ≥ 6.4)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="smtpd" scheme="http://doc.huc.fr.eu.org/fr/tags/smtpd/" />
        <category term="auth" scheme="http://doc.huc.fr.eu.org/fr/tags/auth/" />
        <category term="mail" scheme="http://doc.huc.fr.eu.org/fr/tags/mail/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou, <strong>comment configurer sa machine locale pour envoyer un mail depuis
votre console, depuis OpenBSD, actuellement dans sa version 6.4, en se
connectant à un service nécessitant une identification ?</strong></p>
<h2 id="présentation">Présentation</h2>
<p><strong>OpenSMTPD</strong> est une libre implémentation du protocole SMTP
côté serveur, tel que défini dans la <a href="https://www.rfc-editor.org/info/rfc5321" title="RFC Editor : Information à-propos de la RFC 5321">RFC 5321</a>
, avec
quelques extensions standards additionnels. Il permet à des
machines ordinaire d&rsquo;échanger des mails avec d&rsquo;autres systèmes
parlant le protocole SMTP.</p>
<p>Informations :</p>
<ul>
<li>Site web : <a href="https://www.opensmtpd.org" rel="external">https://www.opensmtpd.org</a></li>
<li>OS : OpenBSD <del>6.4</del> → <strong>7.8</strong></li>
</ul>
<p><em>Testé avec efficacité auprès des services de <a href="https://gandi.net" rel="external">Gandi</a>, de l&rsquo;association
<a href="https://lautre.net" rel="external">L&rsquo;autre.net</a>, puis sur mes propres serveurs MX.</em></p>
<h2 id="installation">Installation</h2>
<p>OpenBSD, depuis sa version 6.4, embarque nativement la nouvelle version
d&rsquo;OpenSMTPD… il n&rsquo;y a donc rien de plus à installer, cela fait partie du
système de base.</p>
<p>Donc, un coup de <code># rcctl start smtpd</code> et c&rsquo;est partie le service SMTP
fonctionnera normalement sur votre machine !</p>
<p>Une petite précision sur les fichiers :</p>
<ul>
<li>le fichier de configuration est : <code>/etc/mail/smtpd.conf</code>.</li>
<li>le fichier log est <code>/var/log/maillog</code> et permet de surveiller toute
l&rsquo;activité liée à SMTP, vous y retrouverez aussi les erreurs d&rsquo;envois.</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Pour envoyer un mail par SMTP à un service de mails nécessitant une
identification, tel que celui de Gandi, il est nécessaire de créer dans
un premier temps, un fichier <code>secrets</code> avec les droits adéquats sur
votre système, ensuite il nous reste à configurer le fichier
<code>smtpd.conf</code>.</p>
<p>Le manpage nous donne un <a href="https://man.openbsd.org/smtpd.conf#EXAMPLES" rel="external">exemple</a>
de ce qu&rsquo;il faut faire - regardez le premier exemple, si besoin, mais je
le restitue ici - :</p>
<h3 id="fichier-secrets">Fichier secrets</h3>
<p>Il nous faut créer ce fichier <code>/etc/mail/secrets</code> :
<code>:# touch /etc/mail/secrets</code></p>
<p><strong>Donnons lui les droits adéquats pour le &ldquo;sécuriser&rdquo;, selon la section
&ldquo;Exemples&rdquo; du manpage</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# chmod <span style="color:#f99b15">640</span> /etc/mail/secrets
</span></span><span style="display:flex;"><span>:# chown root:_smtpd /etc/mail/secrets
</span></span></code></pre></div><p>Ensuite, il est nécessaire de le remplir de telle manière : <br>
<code>identifiant username:password</code> <br>
<span class="red">n'écrivez pas TEXTUELLEMENT cette information</span>
,
remplacez-là par les informations ci-dessous :</p>
<ul>
<li>où <code>identifiant</code> est l&rsquo;identifiant que vous choisissez soigneusement,
et qui vous servira plus tard dans la configuration du fichier
<code>smtpd.conf</code> ;
<em>admettons pour l&rsquo;exemple que ce sera la chaine de caractères :
<strong>perso</strong>.</em></li>
<li><code>username</code> est votre identifiant de connexion mail au service mail de
votre fournisseur - <em>généralement votre adresse mail</em> - ;</li>
<li><code>password</code> étant le mot de passe lié à votre identification mail.</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il est possible de nommer autrement ce fichier secrets, et de le mettre
ailleurs dans votre système de fichier ; comprenez-le principe et modifier
en conséquence.</p>
<p>De même, je vous encourage fortement à ne mettre QUE des droits <strong>0400</strong>
sur le fichier.</p>
<p>Même si l&rsquo;accès au fichier par smtpd peut sans soucis être fait avec vos
droits personnels <code>$USER:$USER</code>,
si vous l&rsquo;avez mis ailleurs, tel que dans votre <code>$HOME</code>, il est préférable
de mettre à minima les droits avec le groupe <code>_smtpd</code>.</p>
</div>

<h3 id="fichier-smtpdconf">Fichier <code>smtpd.conf</code></h3>
<p>Maintenant modifions le fichier <code>/etc/mail/smtpd.conf</code></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#   $OpenBSD: smtpd.conf,v 1.14 2019/11/26 20:14:38 gilles Exp $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># This is the smtpd server system-wide configuration file.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See smtpd.conf(5) for more information.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table aliases file:/etc/mail/aliases</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table secrets file:/etc/mail/secrets</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">queue compression</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># To accept external mail, replace with: listen on all</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## add on 6.7</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen on socket</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen on lo0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">action &#34;local_mail&#34; mbox alias &lt;aliases&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">action &#34;unbound&#34; relay host smtp+tls://identifiant@serveur auth &lt;secrets&gt; mail-from &#34;@your-domain.tld&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Uncomment the following to accept external mail for domain &#34;example.org&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># match from any for domain &#34;example.org&#34; action &#34;local&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### 6.6 writings</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#match for local action &#34;local_mail&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#match for any action &#34;unbound&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">### 6.7 writings</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match from local for local action &#34;local_mail&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">match from local for any action &#34;outbound&#34;</span>
</span></span></code></pre></div><hr>
<p><strong>Explications</strong></p>
<p>Par rapport à la version originale, nous avons donc rajouté :</p>
<ul>
<li>la ligne  <code>table secrets</code> qui appelle le fichier <code>/etc/mail/secrets</code> -
<em>ou son équivalent, si vous l&rsquo;avez personnalisé</em>…</li>
<li>la ligne <code>action unbound</code> qui nous permet de définir l&rsquo;action nécessaire
vers l&rsquo;hôte relais par lequel nous enverrons les mails…
<ul>
<li>REMARQUEZ l&rsquo;écriture  <code>identifiant@serveur</code> :
<ul>
<li>c&rsquo;est justement là qu&rsquo;il faut remplacer la chaîne <code>identifiant</code>
par celle que vous avez créée dans votre fichier <code>secrets</code>.
<em>Dans le contexte de notre exemple, il faudra écrire la chaine
de caractères <strong>perso</strong>.</em></li>
<li>quant à la chaîne <code>serveur</code>, c&rsquo;est le nom du serveur SMTP qu&rsquo;il
faut renseigner.
<ul>
<li><em>dans le cas de Gandi, il faut la
remplacer par l&rsquo;adresse de l&rsquo;hôte mail de Gandi, à savoir : <br>
<code>mail.gandi.net</code></em>.</li>
</ul>
</li>
</ul>
</li>
<li>la chaîne <a href="https://man.openbsd.org/smtpd.conf#host" rel="external">smtp+tls</a> est
le protocol que nous utilisons pour nous connecter au service de
l&rsquo;hôte mail relais… <br>
<em>si vous avez besoin d&rsquo;utiliser un autre protocole, je vous renvoie
à la liste de ceux gérés par OpenSMTPD…</em></li>
<li>la chaîne <a href="https://man.openbsd.org/smtpd.conf#auth" rel="external">auth</a> permet de
spécifier la table <code>secrets</code> fournissant les données d&rsquo;identification
mail nécessaires.</li>
<li>la chaîne <a href="https://man.openbsd.org/smtpd.conf#mail_-from" rel="external">mail-from</a>
nous permet de spécifier le nom de domaine - ce qui permet d&rsquo;éviter
l&rsquo;erreur <code>Sender address rejected: Domain not found</code> ; <br>
<em>il faut bien sûr que ce domaine vous appartienne…</em></li>
<li>la ligne <code>match … action &quot;unbound&quot;</code> est l&rsquo;action qui sera déclenchée
lors de l&rsquo;envoi de mails à l&rsquo;extérieur !</li>
</ul>
</li>
</ul>
<h4 id="changements-67">Changements 6.7</h4>
<p>La v6.7 d&rsquo;OpenBSD a apporté de légers changements de syntaxe :</p>
<ul>
<li>ajout de <code>listen on socket</code> <em>
<a class="" href="https://man.openbsd.org/smtpd.conf.5#listen~2" title="Page du Manuel OpenBSD pour : smtpd.conf">smtpd.conf(5)#listen~2</a>
</em></li>
<li>modification de actions de correspondances du gestionnaire de queues <strong>local</strong> <em>
<a class="" href="https://man.openbsd.org/smtpd.conf.5#match" title="Page du Manuel OpenBSD pour : smtpd.conf">smtpd.conf(5)#match</a>
</em> : <br>
<code>match from local for local action &quot;local_mail&quot;</code> <br>
<code>match from local for any action &quot;outbound&quot;</code> \</li>
</ul>
<h4 id="changements-64--66">Changements 6.4 &gt; 6.6</h4>
<p>La syntaxe des noms d&rsquo;actions a légèrement changé entre les versions 6.4 et 6.6 :</p>
<ul>
<li><code>local</code> devient <code>local_mail</code></li>
<li><code>relay</code> devient <code>unbound</code></li>
</ul>
<h3 id="gestion-des-alias">Gestion des alias</h3>
<p>Il est intéressant de gérer l&rsquo;alias relatif à votre compte <code>root</code> voire
celui de votre utilisateur principal…</p>
<p>Éditez le fichier <code>/etc/mail/aliases</code>, et vers la fin du fichier,
modifiez <code>root</code> en lui indiquant vers quelle adresse mail, vous désirez
que les messages systèmes adressés au compte root vous soit envoyés !</p>
<p>Faites de même pour votre utilisateur système ;)</p>
<p>N&rsquo;oubliez pas de recharger la base des aliases, grâce à l&rsquo;usage de la
commande <code>newaliases</code>… avec des droits administrateurs !</p>
<h2 id="utilisation">Utilisation</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Avant de redémarrer le service smtpd pour qu&rsquo;il prenne en compte les
modifications faites, il nous faut tester l&rsquo;écriture de la
configuration : <code># smtpd -n</code> qui devrait réponde par : <code>configuration OK</code>
informant ainsi que tout va bien…</p>
<p>Sinon, rééditez le fichier de configuration à la ligne indiquée en premier ;
c&rsquo;est d&rsquo;elle que vient l&rsquo;erreur principale !</p>
</div>

<p>Partons du principe que tout est bon, il suffit de redémarrer le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rcctl restart smtpd
</span></span><span style="display:flex;"><span>smtpd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>smtpd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Le journal quant à lui indiquera le bon redémarrage par une ligne d&rsquo;information
semblable à la suivante : <br>
<code>Apr  3 07:17:05 sh1 smtpd[68810]: info: OpenSMTPD 7.0.0 starting</code></p>
<p>De même, pensez à utiliser le contrôleur <code>smtpctl</code>… je vous renvoie à son
manpage qui est très complet !</p>
<h3 id="tests-denvois">Tests d&rsquo;envois</h3>
<p>Soit :</p>
<ul>
<li><code>echo &quot;Test d'envois de mail on $(hostname); date: $(date)&quot; | mail -s &quot;Test de mail&quot; adresse_mail_à_qui_envoyer</code></li>
<li><code>echo &quot;Test d'envois de mail on $(hostname); date: $(date)&quot; | mail -s &quot;Test de mail&quot; root</code></li>
</ul>
<p>Dans un cas, comme dans l&rsquo;autre, le journal vous indiquera
l&rsquo;équivalent, en cas de réussite, d&rsquo;un tel message, par exemple :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">Apr  3 07:20:20 sh1 smtpd[56183]: 2cda1df4efff97f2 mta connecting address=smtp+tls://89.234.141.148:587 host=mail2.automario.eu
Apr  3 07:20:20 sh1 smtpd[56183]: 2cda1df4efff97f2 mta connected
Apr  3 07:20:21 sh1 smtpd[56183]: 2cda1df4efff97f2 mta tls ciphers=TLSv1.3:AEAD-CHACHA20-POLY1305-SHA256:256
Apr  3 07:20:21 sh1 smtpd[56183]: 2cda1df4efff97f2 mta cert-check result=&#34;valid&#34; fingerprint=&#34;SHA256:17af91bcb27a530cc278cd8be90551593bee38ebaf6ade68053a508b14a8f817&#34;
Apr  3 07:20:21 sh1 smtpd[56183]: 2cda1df4efff97f2 mta delivery evpid=4138560f4bd626cf from=&lt;***@huc.fr.eu.org&gt; to=&lt;***@stephane-huc.net&gt; rcpt=&lt;-&gt; source=&#34;46.23.90.29&#34; relay=&#34;89.234.141.148 (mail2.automario.eu)&#34; delay=1s result=&#34;Ok&#34; stat=&#34;250 2.0.0 eb1a48cf Message accepted for delivery&#34;
</code></pre><h2 id="gestion-des-erreurs">Gestion des erreurs</h2>
<p>Retrouvez ci-dessous les erreurs communes liées à une mauvaise configuration :</p>
<h3 id="error-authentication-failed">Error: authentication failed</h3>
<p>Vérifiez, re-vérifiez votre couple d&rsquo;identification <code>username</code>, <code>password</code>
écrits dans votre <a href="/fr/sys/openbsd/smtpd-config-auth/#fichier-etc-mail-secrets">fichier secret</a> !</p>
<h3 id="error-cannot-parse-smarthost">Error: Cannot parse smarthost</h3>
<p>Ce message d&rsquo;erreur est adressé parce que le service SMTP n&rsquo;arrive pas à
comprendre l&rsquo;ensemble <code>identifiant@serveur</code> dans votre règle action.</p>
<p>Vérifiez vos écritures, afin que :</p>
<ul>
<li>votre <code>table secrets</code> renseigne bien le bon nom de fichier à interroger !</li>
<li>vous avez bien écrit une écriture de type <code>identifiant username:password</code>
dans votre fichier <code>secrets</code></li>
<li>vous avez bien remplacez la chaîne <code>identifiant</code> par celle que vous
avez créée…</li>
<li>idem pour la chaîne <code>serveur</code> : assurez-vous de l&rsquo;existence du nom de
l&rsquo;hôte relais.</li>
</ul>
<h3 id="error-sender-address-rejected-domain-not-found">Error: Sender address rejected: Domain not found</h3>
<p>Ce message d&rsquo;erreur vous est adressé lorsque le service SMTP ne trouve
pas de correspondance avec le nom de domaine.</p>
<dl>
<dt>L&rsquo;astuce est d&rsquo;utiliser le paramètre <a href="https://man.openbsd.org/smtpd.conf#mail_-from" rel="external">mail-from</a>,</dt>
<dt>dans la règle action, de manière à cibler votre nom de domaine, tel que</dt>
<dd><code>mail-from &quot;@votre-domaine.tld&quot;</code> <br>
<strong>n&rsquo;oubliez pas la présence du symbole <code>@</code> <em>(arobase)</em>.</strong></dd>
</dl>
<h2 id="documentations">Documentations</h2>
<p>Le protocol SMTP est défini par la RFC 5321 :</p>

<h3 id="rfc-5321">RFC 5321</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc5321" title="RFC 5321 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc5321" title="RFC 5321 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc5321.txt" title="RFC 5321 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc5321.html" title="RFC 5321 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc5321.txt.pdf" title="RFC 5321 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc5321.txt" title="RFC 5321 : au format Text">TXT</a>
	</dd>
</dl>

<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/smtpd.conf.5" title="Page du Manuel OpenBSD pour : smtpd.conf">smtpd.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/smtpctl.8" title="Page du Manuel OpenBSD pour : smtpctl">smtpctl(8)</a>
</li>
</ul>
<h3 id="autres-informations">Autres informations</h3>
<ul>
<li>Retrouvez les différents changements de syntaxe induits par la nouvelle
version d&rsquo;OpenSMTPD : en <a href="https://www.openbsd.org/faq/upgrade64.html" rel="external">Anglais</a>.</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment configurer le service smtpd avec authentification mail sous OpenBSD (≥ v6.4), pour permettre l&#39;accès à vos services de messagerie mails.]]></summary>
        <published>2018-11-03T21:38:54+01:00</published>
        <updated>2026-01-19T14:35:11+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:15570e7f-8fff-4724-37f0-a6833d1d185d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/unbound-control/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Unbound control</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le but de cet article est de montrer comment obtenir les différentes informations
qu&rsquo;unbound permet de surveiller, et se base sur l&rsquo;outil <code>unbound-control</code>.</p>
<h2 id="configuration">Configuration</h2>
<p>Pour rappel :</p>
<ul>
<li>le fichier de configuration est normalement : <code>/var/unbound/etc/unbound.conf</code></li>
<li>la commande pour tester la configuration est : <code>unbound-checkconf</code></li>
</ul>
<p>Je ne rappellerai pas comment configurer pleinement Unbound, lisez cet
article <strong>
<a class="inside" href="/fr/sys/openbsd/unbound/" title="Lien interne vers l&#39;article : 'OpenBSD : utiliser Unbound'">OpenBSD : utiliser Unbound</a>

</strong> et celui-ci pour plus
de &ldquo;sécurité&rdquo; autour des communications DNS <strong>
<a class="inside" href="/fr/sys/openbsd/unbound-dnssec-dns-over-tls/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS'">OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS</a>

</strong> ;-)</p>
<h3 id="unbound-control-setup">unbound-control-setup</h3>
<p>La première chose, à faire sur votre serveur, est l&rsquo;usage de l&rsquo;outil
<code>unbound-control-setup</code>, afin de générer les clés et certificats nécessaires
pour gérer le service :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># unbound-control-setup</span>
</span></span><span style="display:flex;"><span>setup in directory /var/unbound/etc
</span></span><span style="display:flex;"><span>generating unbound_server.key
</span></span><span style="display:flex;"><span>Generating RSA private key, <span style="color:#f99b15">3072</span> bit long modulus
</span></span><span style="display:flex;"><span>...............................................................................................................++
</span></span><span style="display:flex;"><span>............................................................++
</span></span><span style="display:flex;"><span>e is <span style="color:#f99b15">65537</span> <span style="color:#5bc4bf">(</span>0x10001<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>generating unbound_control.key
</span></span><span style="display:flex;"><span>Generating RSA private key, <span style="color:#f99b15">3072</span> bit long modulus
</span></span><span style="display:flex;"><span>........................................................................++
</span></span><span style="display:flex;"><span>..................++
</span></span><span style="display:flex;"><span>e is <span style="color:#f99b15">65537</span> <span style="color:#5bc4bf">(</span>0x10001<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>create unbound_server.pem <span style="color:#5bc4bf">(</span>self signed certificate<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>create unbound_control.pem <span style="color:#5bc4bf">(</span>signed client certificate<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Signature ok
</span></span><span style="display:flex;"><span><span style="color:#ef6155">subject</span><span style="color:#5bc4bf">=</span>/CN<span style="color:#5bc4bf">=</span>unbound-control
</span></span><span style="display:flex;"><span>Getting CA Private Key
</span></span><span style="display:flex;"><span>Setup success. Certificates created. Enable in unbound.conf file to use
</span></span></code></pre></div><p>Les clés et certificats étant générés, il ne reste plus qu&rsquo;à retoucher
le fichier de configuration pour activer le service de gestion de contrôle,
qui permet de le gérer aussi à distance !</p>
<h3 id="unbound-control">unbound-control</h3>
<p>Ouvrons le fichier de configuration d&rsquo;unbound, pour le modifier de manière
adéquate - par défaut, il se présente ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>remote-control:
</span></span><span style="display:flex;"><span>    control-enable: yes
</span></span><span style="display:flex;"><span>    control-use-cert: no
</span></span><span style="display:flex;"><span>    control-interface: /var/run/unbound.sock
</span></span></code></pre></div><p>Pour pouvoir l&rsquo;administrer localement, il est nécessaire de commenter la
déclaration <code>control-interface</code> et d&rsquo;ajouter celles-ci :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>    <span style="color:#776e71">#control-interface: /var/run/unbound.sock</span>
</span></span><span style="display:flex;"><span>    control-interface: 127.0.0.1
</span></span><span style="display:flex;"><span>    control-interface: ::1
</span></span></code></pre></div><p>Il est bien sûr possible de spécifier l&rsquo;adresse IPv4 ou IPv6 du serveur,
celles de votre LAN, ou celles accessibles sur Internet. <br>
Lire les règles de <a href="/fr/sys/openbsd/unbound-control/#pf">pare-feu</a> envisageables pour sécuriser la connexion.</p>
<hr>
<p>Maintenant, après avoir vérifié le fichier de configuration et recharger/relancer
le service unbound, il est possible au moins localement d&rsquo;utiliser l&rsquo;outil
<code>unbound-control</code>.</p>
<p>Lisez ABSOLUMENT le manpage pour savoir quelles sont les différentes options,
voici les plus utiles :</p>
<ul>
<li><code>-c</code> : spécifier un fichier de configuration alternatif</li>
<li><code>-h</code> : obtenir l&rsquo;aide</li>
<li><code>-s</code> : cibler le serveur à interroger ; <em>fonctionne sur IPv4 et IPv6</em> :
<code>server[@port]</code> :
<ul>
<li>si le port n&rsquo;est pas spécifié, ce sera celui par défaut <code>8953</code>,</li>
<li>sinon modifiez-le dans le fichier de configuration.</li>
</ul>
</li>
</ul>
<p>Ensuite, il est possible d&rsquo;envoyer des commandes qui interagiront avec
le serveur, de telle manière : <br>
<code>:$ unbound-control -s 127.0.0.1 command_name</code></p>
<p>Il y a beaucoup de commande possibles, voici certaines :</p>
<ul>
<li>
<p><code>start</code> : démarrer le serveur</p>
</li>
<li>
<p><code>stop</code> : arrêter le serveur</p>
</li>
<li>
<p><code>reload</code> : purge le cache et recharge la configuration</p>
</li>
<li>
<p><code>stats</code> : affiche les statistiques et remets à zéro les compteurs internes</p>
</li>
<li>
<p><code>stats_noreset</code> : affiche les statistiques sans remettre à zéro les
compteurs internes</p>
</li>
<li>
<p><code>status</code> : affiche le status du serveur</p>
<ul>
<li><code>0</code>, s&rsquo;il fonctionne</li>
<li><code>1</code>, s&rsquo;il y a une erreur</li>
<li><code>3</code>, soit s&rsquo;il ne fonctionne pas, soit si la connexion est refusée.</li>
</ul>
</li>
<li>
<p><code>dump_cache</code> permet d&rsquo;afficher/imprimer le contenu du cache ; il est
ainsi possible de le rediriger vers un fichier pour enregistrer ces données.</p>
</li>
<li>
<p><code>load_cache</code> charge le contenu d&rsquo;un cache depuis stdin… aide au débogage.</p>
</li>
<li>
<p><code>get_option //option//</code> pour obtenir la valeur d&rsquo;une option, où <code>option</code>
est le nom de l&rsquo;option</p>
</li>
<li>
<p><code>set_option //option:valeur//</code> permet de définir la valeur d&rsquo;une option… <br>
où <code>option</code> est le nom de l&rsquo;option, et <code>valeur</code>, sa valeur adéquate.</p>
<p>Les options paramétrables sont :</p>
<ul>
<li><code>add-holddown</code>,</li>
<li><code>cache-max-ttl</code>, <code>cache-max-negative-ttl</code>, <code>cache-min-ttl</code></li>
<li><code>del-holddown</code>, <code>do-not-query-localhost</code>,</li>
<li><code>harden-below-nxdomain</code>, <code>harden-dnssec-stripped</code>, <code>harden-glue</code>,
<code>harden-large-queries</code>, <code>harden-referral-path</code>, <code>harden-short-bufsize</code>,</li>
<li><code>hide-identity</code>, <code>hide-version</code>,</li>
<li><code>identity</code>, <code>ignore-cd-flag</code>, <code>ip-ratelimit</code>,</li>
<li><code>keep-missing</code>,</li>
<li><code>log-queries</code>, <code>val-log-level</code>, <code>val-log-squelch</code>,</li>
<li><code>max-udp-size</code>,</li>
<li><code>prefetch</code>, <code>prefetch-key</code>,</li>
<li><code>ratelimit</code>,</li>
<li><code>statistics-cumulative</code>, <code>statistics-interval</code>,</li>
<li><code>ssl-upstream</code>, <code>tcp-upstream</code>,</li>
<li><code>version</code>,</li>
</ul>
</li>
</ul>
<p>Ensuite, il est possible de gèrer :</p>
<ul>
<li>les zones locales <code>local-zone</code></li>
<li>et leurs données <code>local-data</code>,</li>
<li>toutes les options <code>auth_*</code>, <code>dump_*</code>, <code>flush_*</code>, <code>forward_*</code>, <code>insecure_*</code>,
<code>list_*</code>, <code>*ratelimit_*</code>, <code>stub_*</code>, <code>view_*</code></li>
</ul>
<p>mais là, encore une fois, je vous invite à relire le manpage. ;)</p>
<h4 id="exemples">Exemples</h4>
<ul>
<li><code>status</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ unbound-control -s ::1 status
</span></span><span style="display:flex;"><span>version: 1.8.1
</span></span><span style="display:flex;"><span>verbosity: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>threads: <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>modules: <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">[</span> validator iterator <span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>uptime: <span style="color:#f99b15">49932</span> seconds
</span></span><span style="display:flex;"><span>options: reuseport control
</span></span><span style="display:flex;"><span>unbound <span style="color:#5bc4bf">(</span>pid 99951<span style="color:#5bc4bf">)</span> is running…
</span></span></code></pre></div><ul>
<li><code>get_option</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ unbound-control -s ::1 get_option harden-glue
</span></span><span style="display:flex;"><span>yes
</span></span></code></pre></div><ul>
<li><code>dump_cache</code> :
<code>:$ unbound-control -s ::1 dump_cache &gt; dump.unbound</code> <br>
il ne vous reste plus qu&rsquo;à lire le fichier <code>dump.unbound</code> ;
<em>bien sûr, il peut porter tout autre nom que vous désirez</em>.</li>
</ul>
<h3 id="pf">PF</h3>
<p>Voici quelques règles - d&rsquo;exemples - pour le pare-feu 







































































<span lang="en">PF <em>(Packet Filter)</em></span>







































 :</p>
<h4 id="pf--côté-serveur">PF : côté serveur</h4>
<p>Si vous utilisez l&rsquo;option <code>control-interface</code> en permettant que ce soit
l&rsquo;IP publique sur Internet ou sur votre LAN qui soit consultable, il est
fortement recommandé de modifier vos règles PF, afin de n&rsquo;autoriser que le flux
venant d&rsquo;une machine autorisée, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">myhost</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;192.168.1.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">unbound_ctlr</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;8953&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_adm&gt; const { 192.168.1.3, fd0::3 }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blog log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress  proto tcp from &lt;t_adm&gt;  to $myhost port $unbound_ctlr flags S/SA modulate state</span>
</span></span></code></pre></div><p>Autrement dit, on autorise le flux entrant sur l&rsquo;interface <code>egress</code>
depuis les adresses IPv4|6 intégrées dans la table <code>&lt;t_adm&gt;</code> vers le
serveur <code>$myhost</code> sur le port <code>$unbound_ctlr</code>.</p>
<h4 id="pf--côté-station">PF : côté station</h4>
<p>Pour votre station autorisée ayant, par exemple, l&rsquo;adresse IPv4 <code>192.168.1.3</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">myhost</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;192.168.1.3&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server</span>    <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;192.168.1.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">unbound_ctlr</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;8953&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blog log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress inet  proto tcp from $myhost  to $server  port $unbound_ctlr flags S/SA modulate state</span>
</span></span></code></pre></div><p>On autorise le flux sortant de votre machine autorisée vers le serveur sur
le port adéquate… Bien-sûr, faites de même pour IPv6.</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>
<a class="inside" href="/fr/sys/openbsd/unbound/" title="Lien interne vers l&#39;article : 'OpenBSD : utiliser Unbound'">OpenBSD : utiliser Unbound</a>

</li>
<li>
<a class="inside" href="/fr/sys/openbsd/unbound-dnssec-dns-over-tls/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS'">OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS</a>

</li>
</ul>
<h3 id="manpage">Manpage</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/unbound-control.8" title="Page du Manuel OpenBSD pour : unbound-control">unbound-control(8)</a>
</li>
</ul>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment contrôler son service unbound, sous OpenBSD, avec la commande `unbound-control`]]></summary>
        <published>2018-10-23T15:08:43+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1dc95df9-9201-46aa-af98-4bf2b863b69e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/unbound-dnssec-dns-over-tls/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DoT" scheme="http://doc.huc.fr.eu.org/fr/tags/dot/" />
        <category term="TLS" scheme="http://doc.huc.fr.eu.org/fr/tags/tls/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Cet article a pour but de montrer comment configurer le service unbound
pour que celui fasse ses requêtes en tenant compte du protocole DNSSEC,
protocol de chiffrement des données, et aussi pour qu&rsquo;elles soient transmises
en tenant compte du protocol de chiffrement TLS.</p>
<h2 id="configuration">Configuration</h2>
<p>Pour rappel :</p>
<ul>
<li>le fichier de configuration est normalement : <code>/var/unbound/etc/unbound.conf</code></li>
<li>la commande pour tester la configuration est : <code>unbound-checkconf</code></li>
</ul>
<p>Je ne rappellerai pas comment configurer pleinement Unbound, lisez cet
article : <strong>
<a class="inside" href="/fr/sys/openbsd/unbound/" title="Lien interne vers l&#39;article : 'OpenBSD : utiliser Unbound'">OpenBSD : utiliser Unbound</a>

</strong></p>
<h3 id="dnssec">DNSSEC</h3>
<p>La gestion DNSSEC se fait par l&rsquo;usage de l&rsquo;outil <code>unbound-anchor</code> qui crée
un fichier de clé nécessaire et l&rsquo;ajout de la variable <code>auto-trust-anchor-file</code>
qui pointe vers ledit fichier de clés, dans votre fichier de configuration,
tel quel :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">auto-trust-anchor-file: &#34;/var/unbound/db/root.key&#34;</span>
</span></span></code></pre></div><p>Auquel, il faut ajouté le mode de validation DNSSEC : <br></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">module-config: &#34;validator iterator&#34;</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Même si sous OpenBSD, ce fichier de clé est généré automatiquement dès
le premier démarrage, pour générer le fichier de clé :</p>
<p><code># unbound-anchor -u _unbound -a &quot;/var/unbound/db/root.key&quot;</code></p>
<p>L&rsquo;option <code>-u</code> utilise ici le nom utilisateur, par défaut lié au projet
unbound, sous OpenBSD, à savoir <code>_unbound</code>.</p>
</div>

<p>De même, il faut ajouter les variables suivantes à votre propre fichier
de configuration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">harden-below-nxdomain: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">harden-dnssec-stripped: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">harden-referral-path: yes</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>L&rsquo;option <code>harden-referral-path</code>&rsquo; renforce la validation DNSSEC -
<em>c&rsquo;est une option expérimentale, sans norme RFC, et peut poser des problèmes de performances</em> !</li>
</ul>
<p>Depuis la version 1.7.0, unbound a une nouvelle option : <code>aggressive-nsec</code>
qui met en cache les enregistrements NSEC pour générer les réponses rapidement.
Depuis OpenBSD 6.4, unbound est fourni en version 1.8.1, donc profitez-en :  <br>
<code>aggressive-nsec: yes</code> <br></p>
<h3 id="dns-over-tls">DNS over TLS</h3>
<p>Oui, unbound est capable de communiquer aussi avec les serveurs DNS, en
mode protocolaire <strong><abbr title="DNS-over-TLS">DoT</abbr>
</strong> !</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Il est nécessaire de <strong>bien comprendre l&rsquo;impact de l&rsquo;usage de ce mode de communication</strong>.
Du fait d&rsquo;utiliser TLS, la communication semble &ldquo;ralentie&rdquo;, donner la
sensation de lenteur…</p>
<p><em>Cela est plus ou moins sensible selon la puissance de votre machine et
des serveurs interrogés, de la qualité du réseau, etc.</em></p>
</div>

<p>Il faut configurer unbound ainsi, dans un premier temps :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">do-tcp: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ssl-upstream: yes</span>
</span></span></code></pre></div><p><strong>Explications :</strong></p>
<ul>
<li><code>do-tcp</code> indique de communiquer sur le protocole TCP</li>
<li><code>ssl-upstream</code> ou <code>tls-upstream</code> oblige à communiquer sur le protocole TLS.
<ul>
<li><strong><em>Il est important que le(s) serveur(s) DNS interrogés sachent
communiquer sur ce protocole</em>, autrement les requêtes échoueront !</strong></li>
<li>Si les deux options <code>*-upstream</code> sont indiquées, seule la dernière
sera prise en compte.</li>
</ul>
</li>
</ul>
<h4 id="forward">Forward</h4>
<p>Ensuite, il est nécessaire de décommenter - <em>si ce n&rsquo;est pas déjà fait</em> -
la partie <code>forward-zone</code>, pour indiquer le(s) serveur(s) à interroger sur
le port adéquat - par défaut : 853 - tel(s) que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">forward-zone:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">name: &#34;.&#34;                               # use for ALL queries</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-ssl-upstream: yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># FDN DoT</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">## https://www.fdn.fr/ouverture-des-services-dot-doh/</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 80.67.169.12@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 80.67.169.40@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:910:800::12@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2001:910:800::40@853</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># Others</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 9.9.9.9@853               # Quad9</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 1.1.1.1@853               # Cloudflare</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 149.112.112.112@853       # Quad9 secondaire</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 1.0.0.1@853               # Cloudflare secondaire</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2620:fe::fe@853           # Quad9 / IPv6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2606:4700:4700::1111@853  # Cloudflare / IPv6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">forward-addr: 2606:4700:4700::1001@853  # Cloudflare secondaire / IPv6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><p><strong>Explications :</strong></p>
<ul>
<li><code>forward-ssl-upstream</code> ou son pendant <code>forward-tls-upstream</code> -
<em>(cette dernière semble n&rsquo;être pas reconnue… sous OpenBSD)</em> oblige
toutes les requêtes <code>name: &quot;.&quot;</code> à communiquer en mode DoT -
normalement la documentation unbound informe qu&rsquo;il faut aussi configurer
l&rsquo;option <code>ssl-cert-bundle</code>, ou son pendant <code>tls-cert-bundle</code>,
voire l&rsquo;option <code>tls-win-cert</code> pour authentifier les connexions. <br>
Cela ne semble pas nécessaire sous OpenBSD. <em>(&lt;= à confirmer !)</em></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Les serveurs DNS indiqués le sont à titre d&rsquo;exemples et fonctionnels…
mais vous pouvez très bien en ajouter, supprimer d&rsquo;autres, ne le faire
que sur une des deux couches réseaux (soit pour IPv4, soit pour IPv6)…</div>

<h2 id="tests-dnssec">Tests DNSSEC</h2>
<h3 id="dig">Dig</h3>
<p>Un premier test à faire est l&rsquo;usage de la commande <code>dig</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ dig com. SOA +dnssec 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Debian &lt;&lt;&gt;&gt; com. SOA +dnssec 
</span></span><span style="display:flex;"><span>;; global options: +cmd 
</span></span><span style="display:flex;"><span>;; Got answer: 
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">60764</span> 
</span></span><span style="display:flex;"><span>;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 14, ADDITIONAL: <span style="color:#f99b15">1</span> 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Ce qu&rsquo;il faut repérer dans la sortie complète de la commande <code>dig</code> est
sur la ligne <code>flags:</code> : il faut la présence du drapeau <code>ad</code> -
<strong>si celui-ci figure bien, c&rsquo;est bon signe !</strong> :D</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ dig com. SOA +dnssec | grep <span style="color:#48b685">&#34;;; flags&#34;</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: <span style="color:#f99b15">1</span>
</span></span></code></pre></div><h3 id="unbound-host">Unbound-host</h3>
<p>L&rsquo;autre commande à utiliser est la commande <code>unbound-host</code> qui permet de
s&rsquo;assurer du même résultat, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ unbound-host -v -f /var/unbound/db/root.key com.                                                                                         
</span></span><span style="display:flex;"><span>com. has no address <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>com. has no IPv6 address <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>com. has no mail handler record <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ unbound-host -v -f /var/unbound/db/root.key www.ripe.net        
</span></span><span style="display:flex;"><span>www.ripe.net has address 193.0.6.139 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>www.ripe.net has IPv6 address 2001:67c:2e8:22::c100:68b <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>www.ripe.net has no mail handler record <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ unbound-host -v -f /var/unbound/db/root.key www.afnic.fr 
</span></span><span style="display:flex;"><span>www.afnic.fr is an alias <span style="color:#815ba4">for</span> lb01-1.nic.fr. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>lb01-1.nic.fr has address 192.134.5.24 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>lb01-1.nic.fr has IPv6 address 2001:67c:2218:30::24 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>lb01-1.nic.fr has no mail handler record <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ unbound-host -v -f /var/unbound/db/root.key dnssec.cz
</span></span><span style="display:flex;"><span>dnssec.cz has address 217.31.205.51 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz has IPv6 address 2001:1488:0:3::5 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">10</span> mail.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">15</span> mx.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">20</span> bh.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># unbound-host -v -C /var/unbound/etc/unbound.conf dnssec.cz                                                                          </span>
</span></span><span style="display:flex;"><span>dnssec.cz has address 217.31.205.51 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz has IPv6 address 2001:1488:0:3::5 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">10</span> mail.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">15</span> mx.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">20</span> bh.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="navigateur-internet">Navigateur internet</h3>
<p>Un moyen visuel est d&rsquo;ouvrir votre navigateur internet favori, puis d&rsquo;aller
sur les sites suivants :</p>
<ul>
<li><a href="http://www.dnssec.cz" rel="external">http://www.dnssec.cz</a> : si, sur la partie droite, vous
voyez une clé verte, c&rsquo;est tout autant bon signe !</li>
<li><a href="https://en.internet.nl" rel="external">https://en.internet.nl</a> :  cliquez sur le lien titré &ldquo;Test my internet connection&rdquo;</li>
</ul>
<h2 id="documentations">Documentations</h2>
<p>Pour savoir comment :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/openbsd/unbound-control/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound control'">contrôler le service unbound</a>
</li>
</ul>
<h3 id="manpage">Manpage</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/dig" title="Page du Manuel OpenBSD pour : dig">dig</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/unbound.8" title="Page du Manuel OpenBSD pour : unbound">unbound(8)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound.conf.5" title="Page du Manuel OpenBSD pour : unbound.conf">unbound.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound-checkconf.8" title="Page du Manuel OpenBSD pour : unbound-checkconf">unbound-checkconf(8)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound-anchor.8" title="Page du Manuel OpenBSD pour : unbound-anchor">unbound-anchor(8)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound-host" title="Page du Manuel OpenBSD pour : unbound-host">unbound-host</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Configurer le service unbound, sous OpenBSD, pour avoir les requêtes en mode DNSSEC, et DNS/TLS]]></summary>
        <published>2018-10-22T15:08:43+02:00</published>
        <updated>2025-04-16T16:36:09+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:74a5244d-c0da-e141-e13a-cf72a80c8cca</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/upgrade-hardened-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Mettre à niveau son OpenBSD ayant un FS durci</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="upgrade" scheme="http://doc.huc.fr.eu.org/fr/tags/upgrade/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Dans le contexte de mon projet NAS **<a class="inside" href="/fr/sys/openbsd/omv-it-nas/" title="Lien interne vers l&#39;article : ''">OpenBSD Multimedias View-IT</a>

que j&rsquo;ai présenté, il y a quelques jours, j&rsquo;ai <a class="inside" href="/fr/sys/openbsd/harden-openbsd/" title="Lien interne vers l&#39;article : 'OpenBSD : durcir le système de fichier'">durci le système de fichiers OpenBSD</a>
.</p>
<p>L&rsquo;expérience m&rsquo;apprenant que mettre à niveau son OpenBSD sur un système
de fichiers durci n&rsquo;est pas si simple qu&rsquo;on pourrait le croire - et ce
n&rsquo;est pas la faute directement de l&rsquo;installateur d&rsquo;OpenBSD.</p>
<p>À quoi faut-il penser ?</p>
<ul>
<li>à commenter vos écritures dans les fichiers <code>/etc/rc.local</code>, <code>etc/rc.shutdown</code>,
voire <code>/etc/daily.local</code>, ou à les déplacer le temps de la mise à niveau !
<em>(en effet, les services et autres scripts inscrits dedans pourraient
démarrer, s&rsquo;arrêter inutilement, voire de manière impromptue, surtout indésirée !)</em></li>
<li>à remettre le système de fichiers en écriture…</li>
</ul>
<p>Pourquoi ?</p>
<p>Le problème ne se situe pas lors de la mise à jour du système après avoir
récupérer le nouveau <strong>bsd.rd</strong>, l&rsquo;avoir vérifié, puis démarré dessus ;
il se situe après le démarrage du nouveau noyau, lors de l&rsquo;exécution de
certains scripts, qui eux ont besoin d&rsquo;écrire et d&rsquo;interagir sur le système,
mais qui ne le peuvent !</p>
<p>Donc, voici mon nouvel <a class="inside" href="/fr/sys/openbsd/upgrade-hardened-openbsd/" title="Lien interne vers l&#39;article : '[Mini-Tuto] Upgrade Hardened OpenBSD'">article</a>

qui explique comment faire pour mettre à niveau sereinement son système
de fichiers durci, par quelles étapes passer, et les raisons de celles-ci ;-)</p>
<ul>
<li><strong><a class="inside" href="/fr/sys/openbsd/upgrade-hardened-openbsd/" title="Lien interne vers l&#39;article : '[Mini-Tuto] Upgrade Hardened OpenBSD'">[Mini-Tuto] Upgrade Hardened OpenBSD</a></strong></li>
</ul>
<p>Voilà !</p>
<hr>
]]></content>
        
        <published>2018-10-20T20:10:00+02:00</published>
        <updated>2022-04-22T20:34:11+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d0ecfff8-14f8-6b16-2e45-7b95241efdac</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/upgrade-hardened-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [Mini-Tuto] Upgrade Hardened OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="mini-tuto" scheme="http://doc.huc.fr.eu.org/fr/tags/mini-tuto/" />
        <content type="html"><![CDATA[<h2 id="securelevel">Securelevel</h2>
<p>Officiellement, il faut éditer le fichier <code>/etc/rc.securelevel</code> et lui
écrire : <code>sysctl -w kern.securelevel=1</code> puis redémarrer la machine !</p>
<h2 id="système-de-fichiers-en-lecture-seule">Système de fichiers en lecture seule</h2>
<p>Si vous avez eu la bonne idée de durcir votre FS par l&rsquo;usage - <strong>principalement</strong> -
de l&rsquo;option de montage <code>ro</code> sur les principales
partitions de votre système, il va falloir user de l&rsquo;astuce suivante :</p>
<ul>
<li>
<p>Si vous avez une copie de votre fichier <code>/etc/fstab</code>, telle que montrée
dans mon article <strong>
<a class="inside" href="/fr/sys/openbsd/harden-openbsd/" title="Lien interne vers l&#39;article : 'OpenBSD : durcir le système de fichier'">OpenBSD : durcir le système de fichier</a>

</strong>, alors
faites tout simplement en premier : <br>
<code># mv /etc/fstab /root/fstab ; mv /root/fstab.origin /etc/fstab ; chmod 0644 /etc/fstab</code></p>
</li>
<li>
<p>Sinon, si vous n&rsquo;avez pas fait de copie, ce n&rsquo;est pas bien grave, éditez
votre fichier <code>/etc/fstab</code> pour transformer toutes les écritures de
l&rsquo;option <code>ro</code> en <code>rw</code> et mettre en commentaire la ligne déclarant le fichier
de swap mfs pour <code>/dev</code>. Soit vous le faites à la main, soit vous utilisez
ce one-liner : <br>
<code># sed -i -e 's/ro/rw/g;s/swap \/dev mfs \(.*\)/#swap \/dev mfs \1/g' /etc/fstab</code></p>
</li>
</ul>
<p>Ceci étant fait, vérifiez l&rsquo;écriture de votre système de fichier dans
le fichier <code>/etc/fstab</code>, afin d&rsquo;être bien sûr de l&rsquo;écriture de
celui-ci !</p>
<hr>
<p>Pensez à mettre de côté les scripts <code>/etc/rc.local</code>, <code>/etc/rc.shutdown</code>,
voire <code>/etc/daily.local</code>, - <strong>si vous en avez créé</strong> - afin d&rsquo;être
tranquille lors de la mise à niveau !</p>
<p>Puis faites votre procédure de mise à niveau selon le Guide de Migration
fourni par l&rsquo;équipe OpenBSD - <strong>par exemple, celui de la <a href="https://www.openbsd.org/faq/upgrade64.html" rel="external">6.4</a></strong>…</p>
<h4 id="pourquoi-remettre-le-système-de-fichier-en-écriture-">Pourquoi remettre le système de fichier en écriture ?</h4>
<p>En fait, l&rsquo;installateur d&rsquo;OpenBSD passe en <code>rw</code> lors de la mise à
niveau ; le problème se pose après le redémarrage du système mise à
niveau. En effet, logiquement le système va faire exécuter ses routines
liées au script <code>/etc/sysmerge</code> et <code>/etc/rc.firsttime</code> qu&rsquo;il renomme
pour l&rsquo;occasion en <code>*.run</code> respectivement - ce qui a normalement pour
propos d&rsquo;exécuter les utilitaires <code>sysmerge</code>, <code>fw_update</code>
principalement…</p>
<p>Si le système est initialement en mode lecture seule avant la mise à
niveau, lesdits processus échoueront et vous avertiront par des messages
d&rsquo;erreurs vous informant que le système ne peut pas renommer les deux
scripts en <code>*.run</code>, ni exécuter de fait leur contenu, et donc ne peut
finaliser correctement la mise à niveau !</p>
<hr>
<p>Il ne vous restera plus qu&rsquo;à appeler vous-même l&rsquo;exécution des
binaires <code>sysmerge</code>, <code>fw_updates</code> en espérant que tout se passe
correctement… :(</p>
<p>Puis vous pourrez terminer le processus de migration en mettant à jour
les packages ; ceci une fois fait, il ne vous restera plus qu&rsquo;à faire
une analyse de l&rsquo;ensemble du système grâce aux deux outils, l&rsquo;un natif
<code>pkg_check</code>, l&rsquo;autre à installer <code>sysclean</code>.</p>
<p><strong>OU</strong>, alors, à relancer à nouveau la mise à niveau de votre
système, en appelant le binaire <code>bsd.rd</code> au redémarrage de la
machine, <strong>SEULEMENT</strong> après avoir pris les précautions
nécessaires pour remettre le système de fichiers en écriture
avant le redémarrage !</p>
<hr>
<ul>
<li>Remettez en place vos fichiers <code>/etc/rc.local</code>, <code>/etc/rc.shutdown</code>,
voire <code>/etc/daily.local</code>, en veillant à ce que les droits utilisateurs
soient bien liés à <code>root:wheel</code> et en <code>0644</code>.</li>
<li>Remettez votre <a class="inside" href="/fr/sys/openbsd/harden-openbsd/#syst%c3%a8me-de-fichiers-en-lecture-seule" title="Lien interne vers l&#39;article : 'OpenBSD : durcir le système de fichier'">système de fichier en lecture seule</a>
 !</li>
<li>Et, redémarrez votre machine, puis profitez de l&rsquo;utilisation pendant
environ 6 mois, sans avoir à redémarrer ! :p</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment mettre à jour une machine durcie sous OpenBSD]]></summary>
        <published>2018-10-19T01:17:25+01:00</published>
        <updated>2020-05-21T15:05:40+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:64f40d62-2fd3-ba65-7b25-974ec5fdfe00</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/depot-mfp-epson/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Gestion des Imprimantes MFP Epson par depôt</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <category term="dépôt" scheme="http://doc.huc.fr.eu.org/fr/tags/d%C3%A9p%C3%B4t/" />
        <category term="MFP" scheme="http://doc.huc.fr.eu.org/fr/tags/mfp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Cet article devait vous permettre d&rsquo;avoir des binaires debian, pour votre
imprimante multi-fonctions, appelés <abbr title="Multi Function Printer">MFP</abbr>
,
depuis le site de téléchargement de l&rsquo;entreprise Seiko Epson.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><strong>Si votre imprimante utilise le protocole &ldquo;ESC/P-R&rdquo;, vous pouvez installer
le pilote générique <code>printer-driver-escpr</code>, anciennement <em>epson-inkjet-printer-espcr</em>,
fonctionnel pour beaucoup d&rsquo;imprimantes MFP Epson.</strong></div>

<hr>
<p>Pour ce qui est de configurer la partie Scanner, lisez
<a class="inside" href="/fr/sys/debian/mfp-scanner-epson/" title="Lien interne vers l&#39;article : 'MFP Scanner Epson sous Debian/Devuan'">MFP Scanner Epson sous Debian/Devuan</a>.</p>
<h2 id="configuration">Configuration</h2>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h3 id="création-du-fichier-sourceslist">Création du fichier <code>sources.list</code></h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Cette partie était utile jusqu&rsquo;à Jessie. Elle ne fonctionnera pas pour toute
version Debian supérieure, voire Sid !</div>

<p>Avec les droits administrateur, modifiez le fichier <code>sources.list</code> ou
mieux créez un fichier <code>epson.list</code> correspondant :</p>
<pre tabindex="0"><code>:# apt edit-sources epson
deb http://download.ebz.epson.net/dsc/op/stable/debian/ lsb3.2 main
</code></pre><p>La clé GPG est celle-là :</p>
<p><code>:# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 8AA65D56</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Si vous avez correctement configuré votre fichier personnel <code>~/.gnupg/gpg.conf</code>,
il est très possible que vous ayez ce message d&rsquo;erreur concernant la clé
GPG fournie par Epson : <br>
<code>Signature by key E5220FB7014D0FBDA50DFC2BE5E86C008AA65D56 uses weak digest algorithm (SHA1)</code></p>
<p>Cela signifie simplement que leur clé a été créé avec le protocole par
défaut SHA1… bref, <span class="red">une clé peu fiable !!!</span></p>
<p>Vous ne devriez probablement pas l&rsquo;utiliser, mais c&rsquo;est le seul moyen fourni
par eux ; à vous de voir, si vous voulez lui faire confiance ;
en tout cas, <span class="red">ne signez pas une telle clé</span>
!!!</p>
<p><em>cf :
<a class="inside" href="/fr/sec/gpg/du-bon-usage-securise-de-gpg/" title="Lien interne vers l&#39;article : ''">gpg.conf</a>
</em></p>
</div>

<p>Puis mettez à jour votre système !</p>
<h3 id="la-partie-imprimante">La partie Imprimante</h3>
<p>Tous les pilotes EPSON, pour Debian et assimilés, sont disponibles à
partir de l&rsquo;URL suivante : <br>
<a href="http://download.ebz.epson.net/dsc/search/01/search/?OSC=LX" rel="external">http://download.ebz.epson.net/dsc/search/01/search/?OSC=LX</a></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Jusqu&rsquo;à Debian Jessie : Il est nécessaire d&rsquo;avoir le paquet <code>lsb</code>, voire
<code>lsb-base</code>, installé dans le système… Si ce n&rsquo;est pas fait, faites-le !</div>

<p>Certains pilotes sont spécifiques à plusieurs imprimantes ; d&rsquo;autres
sont plus génériques.</p>
<p>L&rsquo;information correspondant au nom de votre MFP est signifiée dans
l&rsquo;onglet <em>Description</em> de la fenêtre <em>Propriétés</em> des binaires
proposés, ou la partie <em>Information</em> de l&rsquo;outil <em>Synaptic</em>.</p>
<p>Autrement, avec l&rsquo;outil apt, faites d&rsquo;abord une recherche : <br>
<code>:# apt-cache search nom_modele</code> <br>
Où <code>nom_modele</code> est le nom du modèle de votre imprimante, tels que <strong>BX525WD</strong>,
<strong>SX210</strong>, <strong>WF-7510</strong>, etc…</p>
<ul>
<li>Si la recherche ne restitue rien, c&rsquo;est que votre modèle n&rsquo;est pas géré…
à moins que votre imprimante gère le protocole ESC/P-R, tel que noté ci-dessus !</li>
<li>Si la recherche restitue une information, installez le pilote correspondant !</li>
</ul>
<hr>
<p>Une fois le(s) pilote(s) installé(s), il vous faut utiliser l&rsquo;outil de
configuration Imprimantes, à partir du menu Systèmes, ou à partir du
navigateur web à l&rsquo;adresse : <code>http://localhost:631</code>, pour installer et
configurer votre MFP.</p>
<h4 id="protocoles-réseaux">Protocoles réseaux</h4>
<p>Le protocole qui fonctionnera à tous les coups est le protocole <strong>lpd</strong>,
tel que : <code>lpd://adr_ip/PASSTHRU</code></p>
<p>D&rsquo;autres protocoles peuvent fonctionner, tel que :</p>
<ul>
<li><strong>ipp</strong> : <code>ipp://adr_ip:631/ipp/print</code></li>
<li><strong>http</strong> : <code>http://adr_ip:631/ipp/print</code></li>
<li>voire <strong>AppSocket/HP JetDirect</strong> : <code>socket://adr_ip:9100</code></li>
<li>les versions &ldquo;sécurisées&rdquo; des protocoles <strong>ipp</strong> et <strong>http</strong>, à savoir
<strong>ipps</strong> et <strong>https</strong> doivent fonctionner, à condition de les configurer
correctement.</li>
</ul>
<p>Même si la détection par protocole <strong>dnssd</strong> semble fonctionner sans soucis,
si les paquets correspondants sont installés, je ne suis personnellement pas
arrivé à utiliser celui-ci au quotidien.</p>
<h3 id="la-partie-scanner">La partie Scanner</h3>
<p>Retrouvez les informations concernant l&rsquo;utilisation et la configuration
de la partie scanner de votre MFP : <a class="inside" href="/fr/sys/debian/mfp-scanner-epson/" title="Lien interne vers l&#39;article : 'MFP Scanner Epson sous Debian/Devuan'">MFP Scanner Epson sous Debian/Devuan</a></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment installer sous Debian une imprimante multifonctions Epson par le biais des dépôts ]]></summary>
        <published>2018-10-16T23:08:40+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a10eb793-9151-502e-25c5-b433a899a0c4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/mfp-epson/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Gestion des imprimantes de marque EPSON (MFP)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <category term="MFP" scheme="http://doc.huc.fr.eu.org/fr/tags/mfp/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il existe <strong>trois moyens différents pour arriver à installer/configurer
une imprimante Epson</strong> :</p>
<ul>
<li>La première méthode d&rsquo;installation utilise le pilote <a href="/fr/sys/debian/mfp-epson/#gutenprint">Gutenprint</a></li>
<li>Par le biais du projet <a href="/fr/sys/debian/mfp-epson/#openprinting">OpenPrinting</a> de la Fondation Linux</li>
<li>Par le biais <a href="/fr/sys/debian/mfp-epson/#seiko-epson">des dépôts de la société Seiko Epson</a> -
<em>mais cette méthode n&rsquo;est pas conseillée, car elle dépend d&rsquo;anciens
paquets relatifs à 


















































<span lang="en">LSB <em>(Linux Standard Base)</em></span>




























































, et ne seront probablement pas
installables</em>.</li>
</ul>
<h2 id="installation">Installation</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il est possible que le fait de connecter votre imprimante sur un port USB3
l&rsquo;empêche de fonctionner correctement. Si vous avez un soucis, essayez de
la connecter sur un port USB2.</div>


<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><strong>Si votre imprimante utilise le protocole &ldquo;ESC/P-R&rdquo;, vous pouvez installer
le pilote générique <code>printer-driver-escpr</code>, anciennement <em>epson-inkjet-printer-espcr</em>,
fonctionnel pour beaucoup d&rsquo;imprimantes MFP Epson.</strong></div>

<h3 id="gutenprint">Gutenprint</h3>
<p>Vérifiez que votre imprimante apparaisse dans la liste suivante sur la
<a href="http://gimp-print.sourceforge.net/p_Supported_Printers.php" rel="external">page du projet</a>…</p>
<p>Si c&rsquo;est le cas, il vous suffit de :</p>
<ul>
<li>connecter votre imprimante à l&rsquo;ordinateur, par le biais du port USB</li>
<li>d&rsquo;allumer celle-ci</li>
<li>ensuite, utilisez le Gestionnaire des Imprimantes pour Ajouter votre imprimante</li>
</ul>
<p>Si cela n&rsquo;est pas le cas, vérifier que le paquet soit installé : <code>printer-driver-gutenprint</code></p>
<p>Pour information :</p>
<ul>
<li>Il peut-être complété des paquets <code>ijsgutenprint</code> <em>(qui est le pilote
GhostScript pour Gutenprint)</em> et <code>ijsgutenprint-ppds</code> ainsi que du
paquet <code>foomatic-db-gutenprint</code></li>
<li>Le paquet <code>gutenprint-locales</code> fournit la gestion internationale des langues.</li>
<li>Il existe aussi le paquet <code>escputil</code> pour assurer la maintenance des
modèles Stylus <em>(nettoyage, alignement des têtes et niveaux d&rsquo;encres)</em>.</li>
<li>Pour finir, si vous utilisez le logiciel Gimp, vous avez le paquet <code>gimp-gutenprint</code>
qui se trouve être un greffon pour assurer correctement l&rsquo;impression
à partir de ce logiciel.</li>
</ul>
<p>Cette méthode permet aussi de gérer votre imprimante si elle fonctionne
sur le réseau. Si celle-ci est supportée, restituez son adresse IP, dans
le Gestionnaire d&rsquo;Imprimantes !</p>
<p>Si malgré tout l&rsquo;imprimante n&rsquo;est pas supporté, essayez soit la
méthode par le biais des dépôts d&rsquo;Epson, soit par ceux d&rsquo;OpenPrinting.</p>
<h3 id="openprinting">OpenPrinting</h3>
<p><strong>OpenPrinting</strong> est le site référence de la <strong>Fondation Linux</strong> qui recense
les imprimantes, certaines marques, certains modèles fonctionnels sous Linux,
grâce principalement au projet Gutenprint.</p>
<p>Dans un premier temps, recherchez dans <a href="https://www.openprinting.org/printers/manufacturer/Epson/" rel="external">la page Epson</a>
si votre imprimante est listée. Si c&rsquo;est le cas, cliquez sur le lien
correspondant… à votre imprimante, pour de plus amples informations.</p>
<p>De deux choses l&rsquo;une, soit votre imprimante est :</p>
<ul>
<li>dans la catégorie <code>Perfectly</code> - très bon signe -</li>
<li>ou la catégorie <code>Mostly</code> - un peu moins bon, mais fonctionnel…</li>
<li>dans la catégorie <code>Partially</code> - support très moyen, voire nul -</li>
<li>ou la catégorie <code>Paperweight</code> - et là, c&rsquo;est encore plus le drame.</li>
</ul>
<p>Si elle n&rsquo;apparaît nulle part … il y a vraiment peu d&rsquo;espoir ! <br>
Désolé … soit il vous faudra patienter, soit elle ne sera jamais
supportée !</p>
<p>Si votre imprimante Epson est référencée dans les deux premières
catégories principalement, tant mieux.</p>
<p>La page &lsquo;<a href="https://openprinting.github.io/downloads/" rel="external">Downloads</a>&rsquo; du site
permet de télécharger des fichiers PPD, mais aussi <strong>Foomatic</strong>, voire des
pilotes <strong>IJS</strong>. Normalement, votre distribution propose depuis ses dépôts
officiels, les-dits fichiers.<br>
Ainsi, par exemple, il est possible d&rsquo;installer les paquets suivants :</p>
<ul>
<li><code>foomatic-db</code></li>
<li><code>openprinting-ppds</code></li>
</ul>
<h3 id="seiko-epson">Seiko Epson</h3>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<p>Cette méthode consiste, pour les imprimantes dites MFP -
<em>MultiFunctions Printers, en anglais</em> - <em>Imprimantes Multifonctions</em>
-, relativement récentes, à utiliser les dépôts que fourni la société
Seiko Epson pour installer et gérer correctement.</p>
<p>Veuillez lire le tuto relatif : 
<a class="inside" href="/fr/sys/debian/depot-mfp-epson/" title="Lien interne vers l&#39;article : 'Debian : Gestion des Imprimantes MFP Epson par depôt'">Debian : Gestion des Imprimantes MFP Epson par depôt</a>

</p>
<hr>
<h2 id="configuration">Configuration</h2>
<p>Une fois le(s) pilote(s) installé(s), il vous faut utiliser l&rsquo;outil de
configuration Imprimantes, à partir du menu &ldquo;Système&rdquo;, ou à partir du
navigateur web à l&rsquo;adresse : <code>http://localhost:631</code>, pour installer et
configurer votre MFP.</p>
<p>Après la phase de configuration, parfois l&rsquo;imprimante ou la partie
scanner ne répond pas. Pensez à redémarrer le service <code>udev</code>… ou, au
pire à redémarrer votre ordinateur !</p>
<h2 id="divers">Divers</h2>
<p>Si malgré ces trois méthodes, votre imprimante de marque Epson n&rsquo;est
pas gérée… <span class="red">Dommage !</span>
</p>
<hr>
<p>Il semble exister un logiciel payant, nommé <strong>TurboPrint for Linux</strong> qui apporte
du support -
<em>(cf : la liste des <a href="https://www.turboprint.info/printers_Epson.html" rel="external">Epson supportées</a>.)</em> <br>
celui-ci gère aussi la colorimétrie de manière professionnelle - <em>à vous de voir…
je n&rsquo;en parlerai pas plus</em>.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment gérer les imprimantes multifonctions Epson sous Debian]]></summary>
        <published>2018-10-16T22:40:34+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:dff50727-dc70-8eee-63cd-f9db8238d0d8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/nas/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Faire d&#39;OpenBSD son NAS - en mode Raid 1C</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="NAS" scheme="http://doc.huc.fr.eu.org/fr/tags/nas/" />
        <category term="Raid1C" scheme="http://doc.huc.fr.eu.org/fr/tags/raid1c/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici mon projet de NAS, basé sur… OpenBSD !</p>
<p>Ce NAS fait fonction de :</p>
<ul>
<li>serveur de fichiers, avec Samba, voire NFS, et mieux par SSH</li>
</ul>
<h3 id="versions-logicielles">Versions logicielles</h3>
<ul>
<li>OS : OpenBSD <em><del>6.3 ⇒</del></em> <strong>7.2</strong></li>
<li>Samba : <strong>4.16.6</strong></li>
<li>SSH : OpenSSH, LibreSSL <em>(natifs, intégrés)</em></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Démarrons sur une clé USB, pour installer le système sur une clé USB voire
un SSD chiffré…
qui servira à enregistrer/diffuser les données, tels que fichiers documents,
audio, vidéo, etc…</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION : Soyez conscient que du fait d&rsquo;avoir le système d&rsquo;exploitation
sur une clé USB, celui-ci sera &ldquo;plus lent&rdquo; que si nous avions un disque dur
dédié !</div>


<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Étant donné que nous faisons un serveur : lors de l&rsquo;installation, au moment de
choisir les jeux d&rsquo;installation, ne les choisissez pas tous, cela ne sert
strictement à rien. Le gain de  place ne sera pas énorme, mais ce sera toujours
cela de pris ; voici les sets à choisir : <br>
<code>-game* -x* +xbase* +xfont*</code>, voire plus court <code>-g* -x* +xb* +xf*</code> !</div>

<h2 id="configuration">Configuration</h2>
<h3 id="durcir-le-système">Durcir le système</h3>
<p>À la fois, pour soulager la clé, mais aussi pour empêcher toute écriture
non désirée ou involontaire, et donc toute modification potentielle du système,
on va modifier le système de fichier de telle manière que l&rsquo;on ne puisse
ni écrire, ni exécuter quoique ce soit sur l&rsquo;ensemble du système de fichiers.</p>
<ul>
<li>
<p>mise en lecture seule <code>ro</code> des partitions suivantes : <code>/</code>, <code>/usr</code>, <code>/usr/</code>
et toutes les autres partitions <code>/usr/*</code> créées logiquement par l&rsquo;installateur</p>
</li>
<li>
<p>mise en <code>nodev,noexec,nosuid</code> des partitions <code>/tmp</code>, et <code>/var</code></p>
</li>
<li>
<p>mise en <code>nodev,noexec,nosuid</code> de la partition  <code>/home</code> - <em>nous pourrions
mettre l&rsquo;option <code>ro</code> néanmoins cela complexifie encore plus le processus,
surtout à la connexion SSH, voire sur les autres protocoles</em>.</p>
</li>
</ul>
<p>Ensuite il faut veiller à monter les périphériques <code>/dev</code> dans un système
de fichier temporaire swap de type <code>mfs</code> afin de ne pas avoir de problèmes
avec les périphériques, avec certains services qui ont besoin de &ldquo;monter&rdquo;
dynamiquement, tel SSH… autrement dans ce cas, les connexions auraient dû
mal à se faire, voire à ne pas s&rsquo;exécuter.</p>
<p>Lire mon article &ldquo;
<a class="inside" href="/fr/sys/openbsd/harden-openbsd/" title="Lien interne vers l&#39;article : 'OpenBSD : durcir le système de fichier'">OpenBSD : durcir le système de fichier</a>

&rdquo; -
<em>retrouvez le script <code>sysmount</code> dans la section
<a href="/fr/sys/openbsd/nas/#fichiers-de-configuration">Fichiers de configuration</a>
ci-dessous, en fin d&rsquo;article…</em></p>
<h3 id="chiffrer-le-disque-dur">Chiffrer le disque dur</h3>
<p>Personnellement, j&rsquo;utilise deux disques durs en mode Raid 1C <em>(à savoir
Raid 1 + chiffrement)</em>.</p>
<p>Puis, un troisième qui sert de sauvegarde, lui aussi chiffré.</p>
<p>Dans ce contexte, j&rsquo;utilise une seule clé USB pour assumer le déchiffrement.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Veuillez lire mon article &quot;
<a class="inside" href="/fr/sys/openbsd/mount-crypt-hd/" title="Lien interne vers l&#39;article : 'OpenBSD : monter un disque dur chiffré automatiquement'">OpenBSD : monter un disque dur chiffré automatiquement</a></p>
<p>&ldquo;…
vous y retrouverez comment chiffrer, mais aussi les informations nécessaires
pour le montage automatique de ces disques.</p>
</div>

<hr>
<p>N&rsquo;oubliez pas de modifier les fichiers <code>/etc/rc.local</code> et <code>/etc/rc.shutdown</code>
pour attacher et monter le disque dur au démarrage et respectivement le
démonter puis le détacher à l&rsquo;extinction du serveur.</p>
<p><em>Retrouvez ces scripts ainsi que le script <code>bioctlr</code> modifié, dans
la section <a href="/fr/sys/openbsd/nas/#fichiers-de-configuration">Fichiers de configuration</a>
ci-dessous, en fin d&rsquo;article…</em></p>
<h3 id="arborescence">Arborescence</h3>
<p>Choisissez une arborescence du disque dur NAS chiffré, une fois attaché et
monté sur <code>/mnt/nas</code>, par exemple, tel que :</p>
<ul>
<li><code>/mnt/nas/Documents</code>  - répertoire de tout document numérique crée par
les utilisateurs, dans leur propre répertoire</li>
<li><code>/mnt/nas/Medias</code> - qui est le répertoire qui recevra tous les fichiers
images, audios, et vidéos, chacuns dans leur répertoire respectif</li>
<li><code>/mnt/nas/P2P</code> - qui sert à déposer les fichiers torrents…</li>
</ul>
<pre tabindex="0"><code>:# mkdir -p /mnt/nas/{Documents,Medias,P2P}
:# mkdir -p /mnt/nas/Medias/{Images,Music,Video}
:# mkdir /mnt/nas/P2P/torrents
</code></pre><p>Dans le répertoire de documents, créez autant de répertoires nécessaires
que d&rsquo;utilisateurs qui se serviront de votre <strong>NAS</strong>,
et liez symboliquement ces répertoires vers les répertoires home des utilisateurs :</p>
<pre tabindex="0"><code>:# mkdir /mnt/nas/Documents/$user
:# chown $user /mnt/nas/Documents/$user
:# chmod 0700 /mnt/nas/Documents/$user
:# ln -s /mnt/nas/Documents/$user /home/$user/Documents
</code></pre><p>Ensuite, liez symboliquement les différents répertoires de médias, et celui
des torrents avec votre utilisateur principal - le premier utilisateur que
vous aurez créé, qui seul aura le droit d&rsquo;écrire dedans.</p>
<pre tabindex="0"><code>:# chown -R $user /mnt/nas/{Medias,P2P}
:# for name in Images Music Video; do ln -s /mnt/nas/Medias/$name /home/$user/$name; done
</code></pre>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Si jamais vous voulez que chacun des utilisateurs systèmes que vous créerez
ait son propre répertoire dans les différents répertoires des médias,
appliquez la même méthode que le code ci-dessus pour la création des répertoires
utilisateurs dans le répertoire des documents, mais faites-le sur le répertoire
des médias, tel que :</p>
<pre tabindex="0"><code>:# for name in Images Music Video; do mkdir -p /mnt/nas/Medias/$user/$name &amp;&amp; ln -s /mnt/nas/Medias/$user/$name /home/$user/$name; done
:# chown -R $user /mnt/nas/Medias/$user
:# chmod 0700 /mnt/nas/Medias/$user
</code></pre></div>

<p>Dans la suite de ce tutoriel, nous resterons sur la situation simple où
seul l&rsquo;utilisateur principal a des droits en écriture sur les trois répertoires
enfants…</p>
<hr>
<p>En cas où vous avez un énième disque dur, qui lui servirait de sauvegarde
des données écrites sur le disque NAS, le script de montage automatique
est profondément modifié pour pouvoir attacher et monter cet autre disque
dur, qui lui aussi sera chiffré, bien sûr !</p>
<p>Actuellement, j&rsquo;utilise <strong>Borg</strong> pour effectuer ma sauvegarde.</p>
<h3 id="fichiers-de-configuration">Fichiers de configuration</h3>
<p>Retrouvez les différents fichiers de configuration disponibles, tels que :</p>
<ul>
<li>Script de montage en lecture seule et/ou accès en écriture du système : <a href="https://framagit.org/hucste/omv-it/blob/master/Administration/sysmount" rel="external">sysmount</a></li>
<li>Script de montage automatique : <a href="https://framagit.org/hucste/omv-it/blob/master/Administration/bioctlr" rel="external">bioctlr</a></li>
<li>Scripts <a href="https://framagit.org/hucste/omv-it/blob/master/etc/rc.local" rel="external">rc.local</a>, <a href="https://framagit.org/hucste/omv-it/blob/master/etc/rc.shutdown" rel="external">rc.shutdown</a>, <a href="https://framagit.org/hucste/omv-it/blob/master/etc/daily.local" rel="external">daily.local</a></li>
</ul>
<h2 id="gestion-des-services">Gestion des services</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ALERTE</strong> : Tous ces services seront automatiquement démarrés que
<strong>si et seulement si</strong> le disque dur chiffré est attaché <strong>ET</strong> monté.
En effet, cela ne sert à rien de les activer et de les démarrer si le
disque dur n&rsquo;est pas correctement monté ;
ils se mettraient en échec inutilement !</p>
<p>Ils seront donc activé à partir du script <code>/etc/rc.local</code> et arrêté avant
l&rsquo;extinction machine, depuis le script <code>/etc/rc.shutdown</code>.</p>
</div>

<h3 id="minidlna">MiniDLNA</h3>
<p>Si vous souhaitez en faire un serveur multimédia, j&rsquo;explique l&rsquo;installation
et surtout la configuration du service MiniDLNA dans l&rsquo;article suivant : <br>
&ldquo;
<a class="inside" href="/fr/sys/openbsd/minidlna/" title="Lien interne vers l&#39;article : 'MiniDLNA (OpenBSD)'">MiniDLNA (OpenBSD)</a>

&rdquo;.</p>
<p>Pour ce qui est de la configuration du fichier <code>/etc/minidlna.conf</code>,
voici les modifications faites :</p>
<ul>
<li><code>friendly_name=OpenBSD Multimedia View-IT</code></li>
<li><code>media_dir=A,/mnt/nas/Medias/your-user/Music</code></li>
<li><code>media_dir=V,/mnt/nas/Medias/your-user/Video</code></li>
<li><code>max_connections=7</code></li>
</ul>
<h3 id="samba">Samba</h3>
<p>Les explications d&rsquo;installation de base sont fournies dans cet article
&ldquo;
<a class="inside" href="/fr/sys/openbsd/samba/" title="Lien interne vers l&#39;article : 'OpenBSD : Introduction à Samba'">OpenBSD : Introduction à Samba</a>

&rdquo;.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Je vous invite à créer un groupe dédié, dans lequel ajouter les différents
utilisateurs - ainsi, nous utiliserons les options d&rsquo;autorisations par groupe,
plutôt que par utilisateurs autorisés :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# groupadd _smb
</span></span><span style="display:flex;"><span>:# usermod -G _smb <span style="color:#ef6155">$user</span>
</span></span></code></pre></div></div>

<p>Concernant les modifications du fichier <code>/etc/samba/smb.conf</code> :</p>
<h4 id="section-global">Section [Global]</h4>
<ul>
<li>
<p><code>interfaces</code> : décommentez-la, et écrivez votre réseau lan IPv4, et si
vous avez la bonne idée d&rsquo;avoir un réseau IPv6 ULA, <em>(de type <code>fd0::/64</code>,
par exemple)</em> alors faites les ajouts adéquats.</p>
</li>
<li>
<p>nommons le serveur : <code>server string = OpenBSD NAS</code></p>
</li>
<li>
<p>renommons le groupe de travail, ou pas : <code>workgroup</code> - <em>personnellement,
je le fais en le renommant par une seule lettre, me facilitant la vie</em> ;)</p>
</li>
<li>
<p>et, n&rsquo;autorisons QUE les adresses IP venant seulements de notre réseau
local : <code>hosts allow = 192.168.1. fd0::/64</code> - <em>Attention à bien modifier
selon vos propres adressages IP…</em></p>
</li>
</ul>
<h4 id="section-homes">Section [homes]</h4>
<p>Utilisons la <strong>section [Homes]</strong> pour autoriser la connexion à nos différents
utilisateurs, à leurs répertoires <strong>Documents</strong>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section [homes]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">browseable</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">No
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        comment = Documents
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        create mask = 0644
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        directory mask = 0700
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        force directory mode = 0700
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        hide dot files = No
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        hide special files = Yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        hosts allow =
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        path = /mnt/nas/Documents/
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        read only = No
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        valid users =
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        write list =</span>
</span></span></code></pre></div><h5 id="explications">Explications</h5>
<ul>
<li>
<p><code>browseable = no</code> : le parcours du répertoire par tout autre que les
utilisateurs autorisés est interdit ;</p>
</li>
<li>
<p><code>create mask</code> force le chmod sur les fichiers créés/ajoutés/modifiés</p>
</li>
<li>
<p><code>directory mask</code> et <code>force directory mode</code> obligent le chmod en question
sur les répertoires.</p>
</li>
<li>
<p><code>hide dot files = No</code> autorise la lecture des fichiers et répertoires
cachés - ce qui pour un utilisateur autorisé, sur ses propres fichiers,
est normal.</p>
</li>
<li>
<p><code>hide special files = Yes</code> empêche la lecture de tout fichier spécial</p>
</li>
<li>
<p><code>hosts allow</code> indiquons IMPÉRATIVEMENT les adresses IP des machines
autorisées à se connecter à ce partage…</p>
</li>
<li>
<p><code>read only</code> : étant que nous voulons autoriser les utilisateurs à écrire/ajouter
leurs propres documents, laissons/mettons la sur <code>no</code></p>
</li>
<li>
<p><code>valid users</code> renfermera les utilisateurs, ou le groupe samba dédié,
autorisés à se connecter à ce partage - <strong>à remplir impérativement</strong> - <br>
c&rsquo;est ici que nous ajouterons, <em>de préférence</em>, le groupe <code>smb</code> que
je vous ai invité à créer dans l&rsquo;astuce au début de ce chapitre,
tel que : <code>valid users = @_smb</code></p>
</li>
<li>
<p><code>write list</code> autorisera seuls les utilisateurs renseignés à pouvoir écrire
dans ce partage ! - <br>
c&rsquo;est ici qu&rsquo;il est préférable d&rsquo;ajouter le groupe samba dédié, créé
plutôt, tel que : <code>write list = @_smb</code></p>
</li>
</ul>
<h4 id="sections-music-et-video">Sections [Music] et [Video]</h4>
<p>Maintenant occupons nous des partages Samba pour les documents audios, et
vidéos - la configuration sera exactement la même, seul le nom de section
change ainsi que les options <code>comment</code>, <code>path</code>… !</p>
<p>Nous appellerons, <em>par préférence</em>, :</p>
<ul>
<li>pour les documents sonores la section correspondante : <code>Section [Music]</code>,</li>
<li>et pour les fichiers vidéos : <code>Section [Video]</code>.</li>
</ul>
<hr>
<ul>
<li>
<p>À la différence du partage <code>[homes]</code>, permettons que ces partages multimédias
soient parcourables par tous : <code>browseable = yes</code>, et <code>guest ok = yes</code></p>
</li>
<li>
<p>Mais nous ne voulons pas que d&rsquo;aucun puisse écrire dedans, l&rsquo;option
<code>read only = yes</code> nous y aidera. De même que l&rsquo;option <code>printable = no</code>
empêchera toute tentative d&rsquo;impression des documents…</p>
</li>
<li>
<p>De même, nous empêcherons toute lecture de fichiers cachés et/ou spéciaux :
<code>hide dot files = yes</code> et <code>hide special files = yes</code></p>
</li>
<li>
<p>L&rsquo;option <code>write list</code> nous permettra d&rsquo;autoriser au moins votre utilisateur
à écrire dedans ! :p</p>
</li>
</ul>
<h5 id="section-music">Section [Music]</h5>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[Music]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">browseable</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    comment = Musique
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    create mask = 0664
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    directory mask = 0755
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ea support = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    force directory mode = 0755
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    guest ok = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    hide dot files = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    hide special files = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    inherit acls = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    inherit permissions = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    path = /mnt/nas/Medias/Music/
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    printable = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    read only = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    store dos attributes = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    write list =</span>
</span></span></code></pre></div><h5 id="section-video">Section [Video]</h5>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[Video]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">browseable</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    comment = Videos
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    create mask = 0664
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    directory mask = 0755
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ea support = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    force directory mode = 0755
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    guest ok = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    hide dot files = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    hide special files = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    inherit acls = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    inherit permissions = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    path = /mnt/nas/Medias/Video/
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    printable = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    read only = yes
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    store dos attributes = no
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    write list =</span>
</span></span></code></pre></div><h3 id="ssh">SSH</h3>
<p>À la différence des autres services, celui-ci sera bel et bien monté normalement
dès le démarrage de la machine… et donc géré depuis le fichier <code>/etc/rc.conf.local</code>
par le biais de l&rsquo;outil <code>rcctl</code>.</p>
<p>En effet, nous voulons pouvoir y accèder à tout moment…</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Veuillez lire mon article suivant sur comment avoir une</p>
<p><a class="inside" href="/fr/sec/ssh/configuration-securisee/" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">configuration et générer des clés sécurisées</a>
,
actuellement !</p>
</div>

<h4 id="sshfs">SSHFS</h4>
<p>Étant donné que mon utilisateur système principal est autorisé à se connecter
en SSH sur le serveur, il est facile de monter localement le système de fichier,
soit par <a href="https://doc.huc.fr.eu.org/fr/sys/openbsd/sshfs/" rel="external">SSHFS</a> en mode console, soit avec un outil graphique, tel
que <a href="https://doc.huc.fr.eu.org/fr/sys/openbsd/gigolo/" rel="external">Gigolo</a>.</p>
<p>C&rsquo;est plus lent qu&rsquo;avec le partage Samba, ce qui est normal du fait de la
couche &ldquo;sécurité&rdquo; lié aux chiffrements de la connexion… <br>
mais c&rsquo;est aussi pratique ET à ma préférence ! :D</p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Fabriquons un NAS, serveur multimédia, serveur de stockage, sous OpenBSD, en utilisant des disques durs chiffrés, dont le mode Raid 1C]]></summary>
        <published>2018-10-15T19:32:40+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:aaafaf95-b00d-0782-748e-cd3de8037511</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/samba/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Introduction à Samba</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Samba" scheme="http://doc.huc.fr.eu.org/fr/tags/samba/" />
        <category term="Introduction" scheme="http://doc.huc.fr.eu.org/fr/tags/introduction/" />
        <category term="Guide" scheme="http://doc.huc.fr.eu.org/fr/tags/guide/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La suite <strong>Samba</strong> est un ensemble de programmes qui implémentent un serveur
pour les protocoles de partage de fichiers, d’imprimantes Windows
<em>(<abbr title="Server Message Block">SMB</abbr>
/<abbr title="Common Internet File System">CIFS</abbr>
)</em>
ainsi que de contrôleur de domaine  compatible avec Active Directory.</p>
<ul>
<li>Site web : <a href="https://www.samba.org/" rel="external">https://www.samba.org/</a></li>
<li>OS : *<em>OpenBSD <em><del>6.3</del> ⇒ 7.3</em></em></li>
<li>Version installée :
<ul>
<li><strong>4.16.6</strong></li>
<li><em><del>6.6, 6.7, 6.8 : <strong>4.9.18</strong></del></em></li>
<li><em><del>6.4, 6.5 : <strong>4.8.5p1, 4.8.11p0</strong></del></em></li>
</ul>
</li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>samba</code></strong> !</p>
<h3 id="modification-système">Modification système</h3>
<p>Il va être nécessaire de créer le répertoire <code>/var/run/samba</code> et
d&rsquo;attribuer les droits systèmes <code>0755</code> sur les répertoires <code>/var/samba</code>
et <code>/var/cache/samba</code>.</p>
<h3 id="gestion-des-utilisateurs">Gestion des utilisateurs</h3>
<p>Il faut créer un premier utilisateur qui sera autorisé :</p>
<p><code># pdbedit -a -u $user</code></p>
<p>La commande <code>pdbedit</code> est utile pour gérer, non seulement les utilisateurs
mais aussi pour vérifier certaines choses, grâce au jeu des options :</p>
<ul>
<li>
<p><code>-a</code> ou <code>--create</code> : pour créer un nouvel utilisateur ; il est nécessaire
d&rsquo;ajouter l&rsquo;option <code>-u</code> avant de spécifier le nom de l&rsquo;utilisateur</p>
</li>
<li>
<p><code>-L</code> ou <code>--list</code> liste les différents utilisateurs gérés, dans un format
simple, abrégé.</p>
</li>
<li>
<p><code>-L -v</code> affiche toutes les informations liées aux différentes informations
utilisateurs, de manière complète. La version contractée <code>-Lv</code> est
fonctionnelle.</p>
</li>
<li>
<p><code>-c</code> ou <code>--account-control</code> permet de spécifier les propriétés du compte
utilisateur… plusieurs drapeaux définissent le contrôle</p>
</li>
<li>
<p><code>-D</code> ou <code>--drive</code> permet de définir la lettre de mappage du lecteur réseau
à utiliser, tel que <code>-D &quot;H: &quot;</code></p>
</li>
<li>
<p><code>-h</code> ou <code>--homedir</code> permet de redéfinir le chemin réseau du répertoire
personnel d&rsquo;un utilisateur</p>
</li>
<li>
<p><code>-l</code> ou <code>--log-basename=/repertoire_des_logs</code> spécifie le répertoire
du fichier journal</p>
</li>
<li>
<p><code>-s</code> ou <code>--configfile=nom_de_fichier_config</code> spécifie le fichier de
configuration.</p>
</li>
<li>
<p><code>-v</code> ou <code>--verbose</code> est le mode verbeux</p>
</li>
<li>
<p><code>-x</code> ou <code>--delete</code> pour supprimer un utilisateur…</p>
</li>
</ul>
<p>Bien sûr, il existe d&rsquo;autres options intéressantes ; lisez le manpage,
<em>installé en même temps que le logiciel samba.</em></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Faites coïncider les noms utilisateurs Samba avec ceux sur votre système
en veillant à utiliser les mêmes mots de passe ; ça vous facilitera la vie.</div>

<h2 id="configuration">Configuration</h2>
<p>Contrairement à ce qu&rsquo;on pense, la configuration n&rsquo;est pas compliquée -
un peu longue, mais pas compliquée ;)</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il semble que le service WINS ne soit pas supporté sous OpenBSD, donc cela
ne sert à rien de modifier les options <code>wins:*</code> - laissez-les commenter !</div>

<p>Tout se fait principalement dans le fichier <code>/etc/samba/smb.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># This is the main Samba configuration file. You should read the</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># smb.conf(5) manual page in order to understand the options listed</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># here. Samba has a huge number of configurable options (perhaps too</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># many!) most of which are not shown in this example</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For a step to step guide on installing, configuring and using samba, </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># read the Samba-HOWTO-Collection. This may be obtained from:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  http://www.samba.org/samba/docs/Samba-HOWTO-Collection.pdf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Many working examples of smb.conf files can be found in the </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Samba-Guide which is generated daily and can be downloaded from: </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  http://www.samba.org/samba/docs/Samba-Guide.pdf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Any line which starts with a ; (semi-colon) or a # (hash) </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># is a comment and is ignored. In this example we will use a #</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># for commentry and a ; for parts of the config file that you</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># may wish to enable</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># NOTE: Whenever you modify this file you should run the command &#34;testparm&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># to check that you have not made any basic syntactic errors. </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#======================= Global Settings =====================================</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[global]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># workgroup = NT-Domain-Name or Workgroup-Name, eg: MIDEARTH</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">workgroup</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">Workgroup</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># server string is the equivalent of the NT Description field</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">server string</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">Samba Server</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Server role. Defines in which mode Samba will operate. Possible</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># values are &#34;standalone server&#34;, &#34;member server&#34;, &#34;classic primary</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># domain controller&#34;, &#34;classic backup domain controller&#34;, &#34;active</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># directory domain controller&#34;.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Most people will want &#34;standalone server&#34; or &#34;member server&#34;.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Running as &#34;active directory domain controller&#34; will require first</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># running &#34;samba-tool domain provision&#34; to wipe databases and create a</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># new domain.</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">server role</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">standalone server</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># This option is important for security. It allows you to restrict</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># connections to machines which are on your local network. The</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># following example restricts access to two C class networks and</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># the &#34;loopback&#34; interface. For more examples of the syntax see</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># the smb.conf man page</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   hosts allow = 192.168.1. 192.168.2. 127.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Uncomment this if you want a guest account, you must add this to /etc/passwd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># otherwise the user &#34;nobody&#34; is used</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  guest account = pcguest</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># this tells Samba to use a separate log file for each machine</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># that connects</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">log file</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">/var/log/samba/smbd.%m</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Put a capping on the size of the log files (in Kb).</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">max log size</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">50</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Specifies the Kerberos or Active Directory realm the host is part of</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   realm = MY_REALM</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Backend to store user information in. New installations should </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use either tdbsam or ldapsam. smbpasswd is available for backwards </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># compatibility. tdbsam requires no further configuration.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   passdb backend = tdbsam</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Using the following line enables you to customise your configuration</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># on a per machine basis. The %m gets replaced with the netbios name</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># of the machine that is connecting.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Note: Consider carefully the location in the configuration file of</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#       this line.  The included file is read at that point.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   include = /usr/local/samba/lib/smb.conf.%m</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Configure Samba to use multiple interfaces</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># If you have multiple network interfaces then you must list them</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># here. See the man page for details.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   interfaces = 192.168.12.2/24 192.168.13.2/24 </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Where to store roving profiles (only for Win95 and WinNT)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#        %L substitutes for this servers netbios name, %U is username</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#        You must uncomment the [Profiles] share below</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   logon path = \\%L\Profiles\%U</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Windows Internet Name Serving Support Section:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># WINS Support - Tells the NMBD component of Samba to enable it&#39;s WINS Server</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   wins support = yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># WINS Server - Tells the NMBD components of Samba to be a WINS Client</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#       Note: Samba can be either a WINS Server, or a WINS Client, but NOT both</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   wins server = w.x.y.z</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># WINS Proxy - Tells Samba to answer name resolution queries on</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># behalf of a non WINS capable client, for this to work there must be</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># at least one  WINS Server on the network. The default is NO.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   wins proxy = yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># via DNS nslookups. The default is NO.</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">dns proxy</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">no </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># These scripts are used on a domain controller or stand-alone </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># machine to add or delete corresponding unix accounts</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  add user script = /usr/sbin/useradd %u</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  add group script = /usr/sbin/groupadd %g</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  delete user script = /usr/sbin/userdel %u</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  delete user from group script = /usr/sbin/deluser %u %g</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;  delete group script = /usr/sbin/groupdel %g</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#============================ Share Definitions ==============================</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[homes]</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">comment</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">Home Directories
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">   browseable = no</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   follow symlinks = yes</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">;   wide links = yes</span>
</span></span><span style="display:flex;"><span>   <span style="color:#06b6ef">writable</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><hr>
<p>Les options importantes en terme de sécurité sont :</p>
<ul>
<li><code>hosts allow</code> permet de restreindre l&rsquo;accès à un réseau local, une adresse
IP précise, et empêchera tout autre hôte à se connecter.</li>
<li><code>interfaces</code> permet de cibler sur quelle interface réseau les services
de Samba seront diffusés et autorisés.</li>
<li><code>valid users</code> permet de spécifier quels utilisateurs ou groupe d&rsquo;utilisateurs
ont le droit d&rsquo;accéder aux différents partages, ou services fournis.</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Garder à l&rsquo;esprit que le fichier de configuration est, de base, minimaliste,
et dans l&rsquo;état n&rsquo;offre aucune sécurité !</p>
<p>J&rsquo;attire votre attention sur le manpage très long de smb.conf(5),
disponible de par l&rsquo;installation du paquet samba.</p>
</div>

<p>Pour les besoins de test de fonctionnement, ne pas toucher au reste de la configuration…</p>
<h3 id="test">Test</h3>
<p>La commande <code>testparm</code> est utile pour vérifier que le configuration du
fichier soit correcte.</p>
<p><strong>À exécuter AVANT de démarrer le service, et APRÈS toute modification…</strong></p>
<h3 id="weak-crypto-allowed">Weak crypto allowed</h3>
<p>Si <strong>testparm</strong> se plaint du message suivant :
<code>Weak crypto is allowed</code> <br>
Sachez qu&rsquo;il n&rsquo;est rien possible de faire, à moins d&rsquo;utiliser le mode FIPS
seulement.</p>
<p>Cela ne signifie pas que Samba utilise une cryptographie faible, ou qu&rsquo;elle
est permise. Dans les faits, Samba utilise GnuTLS, qui dans des contextes
de compatibilité, basculera sur de faibles algorithmes cryptographiques
autorisés par GnuTLS.</p>
<p>Et, oui, le message n&rsquo;est pas clair !</p>
<hr>
<p>Pour plus d&rsquo;informations:</p>
<ul>
<li>lire la <a href="https://gitlab.com/samba-team/samba/-/merge_requests/2537" rel="external">MR #12537</a></li>
<li>le thread &ldquo;<a href="https://www.spinics.net/lists/samba/msg174767.html" rel="external">weak crypto is allowed</a>&rdquo;
et suivre les messages.</li>
</ul>
<h3 id="limites-systèmes">Limites systèmes</h3>
<p>Il est nécessaire de reconfigurer les limites systèmes en ajoutant :</p>
<ul>
<li>le fichier <code>/etc/login.conf.d/samba</code> pour y ajouter le bloc suivant :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">samba:\</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">:openfiles-max</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">16384:\
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    :tc=daemon:</span>
</span></span></code></pre></div><ul>
<li>le fichier <code>/etc/sysctl.conf</code> pour modifier de manière permanente
<code>kern.maxfiles</code> : <br> <code>kern.maxfiles=16384</code></li>
</ul>
<p>Ces modifications systèmes nécessitent au plus simple de redémarrer
votre machine !</p>
<h3 id="pf">PF</h3>
<p>Les règles pour le pare-feu <abbr title="Packet Filter">PF</abbr>
 sont très
simples à paramétrer :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># lan: IPv4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">lan</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;192.168.1.0/24&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># adress IPv4 of my host</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">myhost</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;192.168.1.1&#34; </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">smb_ports_tcp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 135 137 139 445 }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">smb_ports_udp</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;{ 135 137 138 445 }&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(...)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress  proto tcp from $lan  to $myhost   port $smb_ports_tcp flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress  proto udp from $lan  to $myhost   port $smb_ports_udp allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress inet  proto udp from $myhost  to $lan  port 138 allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress  proto tcp from $myhost to $lan  port $smb_ports_tcp flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out quick on egress  proto udp from $myhost to $lan  port $smb_ports_udp allow-opts </span>
</span></span></code></pre></div><p>Elles sont à configurer et sur le serveur Samba, et sur votre station.</p>
<p>Bien sûr, ces règles sont un exemple ; il faut les adapter à vos besoins.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Faire de même pour la pile IPv6 - afin de différencier facilement les règles
relatives aux deux couches réseau - même si PF sait très bien gérer, avec
une règle simple…</div>

<h2 id="dépannage">Dépannage</h2>
<h3 id="65-smbdtimeouts">6.5: smbd(timeouts)</h3>
<p>Sous OpenBSD 6.5, il y a un problème avec le lancement de Samba, créant des
<code>timeouts</code>.</p>
<p>J&rsquo;explique sur le <a href="https://forum.openbsd.fr.eu.org/showthread.php?tid=2322&amp;pid=18303#pid18303" rel="external">forum de la communauté française &ldquo;OpenBSD Pour Tous&rdquo;</a>
la raison et le fait qu&rsquo;il est nécessaire de lancer à nouveau le service samba ;
pas de le relancer, <strong>juste le démarrer</strong> !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl start samba</span>
</span></span><span style="display:flex;"><span>smbd<span style="color:#5bc4bf">(</span>timeout<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl check samba</span>
</span></span><span style="display:flex;"><span>smbd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>nmbd<span style="color:#5bc4bf">(</span>failed<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start samba</span>
</span></span><span style="display:flex;"><span>nmbd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#rcctl check samba</span>
</span></span><span style="display:flex;"><span>smbd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>nmbd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Il est possible de vérifier que les processus soient bien lancés : <br>
<code>$ ps auxw | grep mbd</code> <br>
<em>(faites le après le timeout et après la deuxième exécution du start,
vous comprendrez !)</em></p>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li><code>man 8 pdbedit</code>, <code>man 5 smb.conf</code></li>
</ul>
<h3 id="samba">Samba</h3>
<p>Ainsi que le met en exergue le manpage de <code>smb.conf</code>, il est fortement
conseillé de lire les deux guides suivants, fournis par le projet :</p>
<ul>
<li>Sur le <a href="https://wiki.samba.org/index.php/Main_Page" rel="external">wiki officiel</a></li>
<li>le Guide <strong><a href="http://www.samba.org/samba/docs/Samba-HOWTO-Collection.pdf" rel="external">Samba-HOWTO-Collection</a></strong> à-propos des différentes étapes
d&rsquo;installation, de configuration et d&rsquo;usage de Samba.</li>
<li>le <strong><a href="http://www.samba.org/samba/docs/Samba-Guide.pdf" rel="external">Guide Samba</a></strong> qui fournit beaucoup d&rsquo;exemples…</li>
</ul>
<p>Ces guides sont basés sur Samba v3. Et, même si nous utilisons une version
supérieure, il y a toujours quelque chose de bon à en tirer, à en apprendre…</p>
<p>Localement sur le système, retrouvez les fichiers de :</p>
<ul>
<li>pkg-readme : <code>/usr/local/share/doc/pkg-readmes/samba</code></li>
<li>et d&rsquo;exemple : <code>/usr/local/share/examples/samba/smb.conf.default</code></li>
</ul>
<hr>
<p><em><strong>Enjoy-ID <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Guide de démarrage : Faire fonctionner le serveur Samba sous OpenBSD]]></summary>
        <published>2018-10-13T19:32:40+02:00</published>
        <updated>2023-05-02T16:04:51+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a8dda8a9-978a-a0da-9ad7-f591e860b543</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/harden-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : durcir le système de fichier</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <content type="html"><![CDATA[<h2 id="securelevel">Securelevel</h2>
<p>Par défaut, actuellement le niveau de sécurité par défaut d&rsquo;OpenBSD
semble être déjà un acquis.</p>
<p>Le manpage <strong>securelevel</strong> nous restitue une information pertinente. Il
est possible d&rsquo;augmenter ce niveau en utilisant la commande <code>sysctl</code>,
telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># sysctl -w kern.securelevel=2</span>
</span></span></code></pre></div><p>Mais soyez conscient des difficultés créées :</p>
<ul>
<li>Impossible de modifier l&rsquo;horloge système - <em>(pensez à la synchronisation
NTP, par exemple…)</em> -,</li>
<li>ou vos règles PF si jamais vous les avez configurées,</li>
<li>etc…</li>
</ul>
<h2 id="système-de-fichiers-en-lecture-seule">Système de fichiers en lecture seule</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Avec OpenBSD 6.4, il semble que cela pose plus
d&rsquo;un soucis. Les sockets qui ne peuvent être copiées ; les
services qui ne peuvent être démarrés, voire redémarrés ; la
régénération du kernel qui ne se fait pas ; les logs PF non
consultables, etc…</p>
<p>et unveil(2) qui logiquement se plaint !</p>
<p><code>(…) unveil: Read-only file system</code></p>
</div>

<p>Un autre moyen est de rester en <code>securelevel</code> par défaut à <code>1</code>, mais
d&rsquo;utiliser les options de montage, tel que <code>ro</code> principalement, mais
aussi <code>nodev,noexec,nosuid</code> sur les différentes partitions du système de
fichier ffs.</p>
<p>Pour cela, il faut d&rsquo;abord modifier le fichier <code>/etc/fstab</code>, de manière
à ce que soit créé au démarrage un système de fichier <code>mfs</code> <em>(swap)</em>
pour monter les périphériques <code>/dev</code> dedans</p>
<p><span class="red">Ne pas oublier cette écriture, sinon, vous aurez quelques 
difficultés pour "monter" dynamiquement certains périphériques spéciaux</span>
,
parfois nécessaires, pour certains services, tel SSH !</p>
<p>Copiez votre fichier <code>/etc/fstab</code> de manière à en faire une sauvegarde -
cela pourrait être utile plus tard !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># cp /etc/fstab /root/fstab.origin ; chmod 0400 /root/fstab.origin</span>
</span></span></code></pre></div><h4 id="modification-du-fichier-etcfstab">Modification du fichier <code>/etc/fstab</code></h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.b none swap sw</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.a / ffs ro 1 1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.k /home ffs ro,nodev,noexec,nosuid 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.d /tmp ffs rw,nodev,noexec,nosuid 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.f /usr ffs ro,nodev 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.g /usr/X11R6 ffs ro,nodev 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.h /usr/local ffs ro,nodev,wxallowed 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.j /usr/obj ffs ro,nodev,nosuid 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.i /usr/src ffs ro,nodev,nosuid 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">duid_info.e /var ffs rw,nodev,noexec,nosuid 1 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">swap /dev mfs rw,-i</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1024,-P=/dev,-s=32m 0 0</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> à ces deux points essentiels :</p>
<ul>
<li>la partition <code>/tmp</code>, et <code>/var</code> ont besoin de rester en écriture ;
néanmoins, il n&rsquo;est pas nécessaire d&rsquo;avoir des droits en exécution,
ni suid, ni d&rsquo;écriture de périphériques spéciaux.</li>
<li>la partition <code>/home</code> peut être en lecture seule ; néanmoins, soyez
conscient que cela vous compliquera la tâche pour ajouter/créer/détruire
tout fichier dans votre répertoire personnel, surtout dans le contexte
d&rsquo;une machine. <br>
De même si vous souhaitez tester du code <em>(python, shell, …)</em>
après avoir cloné des dépôts git, compiler des binaires pour les tester… <br>
dans ce cas-là, c&rsquo;est l&rsquo;option <code>noexec</code> qui vous empêchera une telle
activité, somme toute légitime. <br>
<em>À vous de voir…</em></li>
</ul></div>

<h4 id="création-du-fichier-sysmount">Création du fichier <code>sysmount</code></h4>
<p>Le script <a href="https://framagit.org/hucste/omv-it/blob/master/Administration/sysmount" rel="external"><code>sysmount</code></a>
nous facilitera la vie, pour autoriser l&rsquo;écriture et verrouiller des
différentes partitions le nécessitant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#set -x</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Author: Stéphane HUC</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mail: devs@stephane-huc.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># License: BSD Simplified</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Github:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Date: 2018/10/10</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">arg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;$1&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   FUNCTIONS</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mount FS in rw mode</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rw() {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">printf &#34;%s \n&#34; &#34;*** Mount FS in rw mode! ***&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -uw /</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -uw /usr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -uw /usr/X11R6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -uw /usr/local</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">printf &#34;%s \n&#34; &#34;--- DONE! ---&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#mount FS in ro mode</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ro() {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">printf &#34;%s \n&#34; &#34;*** Mount FS in ro mode! ***&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -ur /usr/local</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -ur /usr/X11R6</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -ur /usr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">mount -ur /</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">printf &#34;%s \n&#34; &#34;--- DONE! ---&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   EXECUTION</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">################################################################################</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if [ &#34;${arg}&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;rw&#34; ]; then rw; elif [ &#34;${arg}&#34; = &#34;ro&#34; ]; then ro; fi</span>
</span></span></code></pre></div><p>L&rsquo;usage en est très simple : avant l&rsquo;installation d&rsquo;un binaire, ou la
modification d&rsquo;un fichier de configuration, un coup de :</p>
<ul>
<li><code>./sysmount rw</code> pour autoriser l&rsquo;écriture sur le système de fichier,</li>
<li>puis ensuite de <code>./sysmount ro</code> pour l&rsquo;empêcher à nouveau`</li>
</ul>
<p>et, voilà !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>Soyez attentif</strong> au fait que ce script ne gère QUE les droits
d&rsquo;écriture sur la racine ainsi que les partitions <code>/usr/</code>
principales…</p>
<p>Il vous faudra le modifier en conséquence pour gérer soit d&rsquo;autres
partitions, soit d&rsquo;autres options !</p>
</div>

<hr>
<p>Lorsqu&rsquo;il faudra mettre à niveau le système d&rsquo;exploitation, veuillez
lire cet autre article : <strong>
<a class="inside" href="/fr/sys/openbsd/upgrade-hardened-openbsd/" title="Lien interne vers l&#39;article : '[Mini-Tuto] Upgrade Hardened OpenBSD'">[Mini-Tuto] Upgrade Hardened OpenBSD</a>

</strong></p>
<hr>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/securelevel" title="Page du Manuel OpenBSD pour : securelevel">securelevel</a>
, 
<a class="man" href="https://man.openbsd.org/unveil.2" title="Page du Manuel OpenBSD pour : unveil">unveil(2)</a>
</li>
</ul>
<h2 id="remerciements">Remerciements</h2>
<p>Un petit &ldquo;gros&rdquo; merci
@<a href="http://www.vincentdelft.be/" rel="external">Vincent</a> pour ces tutoriels
sur le durcissement du système de fichier OpenBSD :
<a href="http://www.vincentdelft.be/post/post_20160712" rel="external">ici</a> ou
<a href="http://www.vincentdelft.be/post/post_20180713" rel="external">là</a>.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment durcir sa machine sous OpenBSD]]></summary>
        <published>2018-10-11T18:43:18+01:00</published>
        <updated>2020-05-21T15:00:40+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b44376a3-2f80-f485-fb3d-31c457267453</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/tumfatig.net/openbsd-raspberry-pi3/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Faire fonctionner OpenBSD sur le Raspberry Pi 3</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Raspberry" scheme="http://doc.huc.fr.eu.org/fr/tags/raspberry/" />
        <category term="Pi3" scheme="http://doc.huc.fr.eu.org/fr/tags/pi3/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://www.tumfatig.net/20180706/running-openbsd-on-raspberry-pi-3/" rel="external">Running OpenBSD on Raspberry Pi 3</a></strong>&rdquo;,
écrit par Joel Carnat.</p>
<hr>
<h1 id="faire-fonctionner-openbsd-sur-le-raspberry-pi-3">Faire fonctionner OpenBSD sur le Raspberry Pi 3</h1>
<ul>
<li>OS concerné : <strong>OpenBSD 6.3 et &gt;</strong></li>
</ul>
<hr>
<ul>
<li>Étape 1 : avoir dans les mains un Raspbian</li>
<li>Étape 2 : exécuté OpenBSD sur le modèle B du Raspberry Pi 3. J&rsquo;ai eu
pas mal d&rsquo;essais et d&rsquo;échecs, mais il a démarré, a été installé et
à la fin, il fonctionne correctement. Voici l&rsquo;histoire complète.</li>
</ul>
<h2 id="le-matériel">Le matériel</h2>
<figure>
    <a href="/images/tumfatig.net/OpenBSD-RPI3.jpg" title="Raspberry Pi 3 ">
    <picture>
        
        <source srcset="/images/tumfatig.net/OpenBSD-RPI3_hu_87b1eb9e5ff3f86e.webp" type="image/webp">
        
        <img alt="Raspberry Pi 3 " height="250" loading="lazy" src="/images/tumfatig.net/OpenBSD-RPI3_hu_5a6c375dc6ae2d7e.jpg" type="image/jpeg" width="250">
    </picture>
    </a>
    <figcaption>Raspberry Pi 3 </figcaption>
</figure>
<p>Pour installer OpenBSD 6.3 sur le Raspberry Pi 3 v1.2, j&rsquo;ai utilisé une
microSD de 128 Mo (pour héberger l&rsquo;installateur), un adaptateur USB pour
la microSD, une clé USB sans marque de 30 Go, un convertisseur USB-TTL
et un câble RJ45.</p>
<p>Tout a été fait depuis un Macbook Pro utilisant MacOS 10.13.5. Les
commandes de préparation ne devraient pas différer beaucoup si vous
utilisez un des *BSD ou Linux.</p>
<p>J&rsquo;ai démarré les deux versions d&rsquo;OpenBSD 6.3, la stable et la current
mais le support matériel était le même. Pas d&rsquo;interface Wifi…</p>
<h2 id="procédure-étape-par-étape">Procédure Étape par Étape</h2>
<p>Récupérez votre fichier d&rsquo;installation d&rsquo;OpenBSD favori. J&rsquo;ai utilisé
miniroot63.fs.</p>
<p>Formatez votre microSD et votre clé USB. Cela n&rsquo;est absolument pas
requis mais je préfère démarrer vraiment vide.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># diskutil list</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil unmountDisk /dev/disk2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># dd if=/dev/zero of=/dev/disk2 count=4096</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil eject /dev/disk2</span>
</span></span><span style="display:flex;"><span>Disk /dev/disk2 ejected
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil unmountDisk /dev/disk3</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># dd if=/dev/zero of=/dev/disk3 count=4096</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil eject /dev/disk3</span>
</span></span><span style="display:flex;"><span>Disk /dev/disk3 ejected
</span></span></code></pre></div><p>Insérez la microSD au dos du MacBook, ignorez les messages
d&rsquo;initialisation de MacOS et copiez le fichier miniroot.fs sur la carte.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># diskutil list</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>/dev/disk2 <span style="color:#5bc4bf">(</span>external, physical<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span><span style="color:#776e71">#: TYPE NAME SIZE IDENTIFIER</span>
</span></span><span style="display:flex;"><span>0: *126.0 MB disk2
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># dd if=miniroot63.fs of=/dev/disk2 bs=1m</span>
</span></span><span style="display:flex;"><span>21+0 records in
</span></span><span style="display:flex;"><span>21+0 records out
</span></span><span style="display:flex;"><span><span style="color:#f99b15">22020096</span> bytes transferred in 7.937130 secs <span style="color:#5bc4bf">(</span><span style="color:#f99b15">2774315</span> bytes/sec<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil list</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>/dev/disk2 <span style="color:#5bc4bf">(</span>external, physical<span style="color:#5bc4bf">)</span>:
</span></span><span style="display:flex;"><span><span style="color:#776e71">#: TYPE NAME SIZE IDENTIFIER</span>
</span></span><span style="display:flex;"><span>0: FDisk_partition_scheme *126.0 MB disk2
</span></span><span style="display:flex;"><span>1: Windows_FAT_32 BOOT 4.2 MB disk2s1
</span></span><span style="display:flex;"><span>2: OpenBSD 13.6 MB disk2s4
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># diskutil eject /dev/disk2</span>
</span></span><span style="display:flex;"><span>Disk /dev/disk2 ejected
</span></span></code></pre></div><p>Pour être capable de démarrer depuis la clé USB, le Raspberry a été
&ldquo;patché&rdquo;. Cela a été fait en ajoutant un drapeau dans le OTP. Vous
devrez insérer la microSD dans le Mac, et éditer le fichier
<code>BOOT/config.txt</code>  en ajoutant une simple ligne de code.</p>
<p>|# echo &ldquo;program_usb_boot_mode=1&rdquo; &raquo; /Volumes/BOOT/config.txt|</p>
<p>Insérez la microSD dans le slot microSD du RPI3, la clé USB dans un des
connecteurs USB du RPI3. Connectez le câble Ethernet au RPI3. Connectez
le RPI3 et le MacBook en utilisant l&rsquo;adaptateur USB TTL.</p>
<p>Depuis mon terminal, j&rsquo;ai utilisé les commandes suivantes pour accéder
à la console :</p>
<p><code># cu -l /dev/cu.usbserial -s 115200 | tee cu.log</code></p>
<p>Branchez le câble électrique microUSB au RPI3. J&rsquo;ai utilisé un câble
microUSB-USB et l&rsquo;ai connecté au port USB3 de mon Synology. Cela a
fonctionné. Bien que la console émette parfois des messages
d&rsquo;avertissements relatifs à la tension.</p>
<p>Vérifiez dans la console que tout démarre :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>U-Boot 2018.03 <span style="color:#5bc4bf">(</span>Mar <span style="color:#f99b15">20</span> <span style="color:#f99b15">2018</span> - 04:28:27 -0600<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DRAM: <span style="color:#f99b15">948</span> MiB
</span></span><span style="display:flex;"><span>RPI <span style="color:#f99b15">3</span> Model B <span style="color:#5bc4bf">(</span>0xa02082<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>U-Boot 2018.03 <span style="color:#5bc4bf">(</span>Mar <span style="color:#f99b15">20</span> <span style="color:#f99b15">2018</span> - 04:28:27 -0600<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DRAM: <span style="color:#f99b15">948</span> MiB
</span></span><span style="display:flex;"><span>RPI <span style="color:#f99b15">3</span> Model B <span style="color:#5bc4bf">(</span>0xa02082<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>MMC: mmc@7e202000: 0, sdhci@7e300000: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Loading Environment from FAT… *** Warning - bad CRC, using default environment
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Failed <span style="color:#5bc4bf">(</span>-5<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>In: serial
</span></span><span style="display:flex;"><span>Out: vidconsole
</span></span><span style="display:flex;"><span>Err: vidconsole
</span></span><span style="display:flex;"><span>Net: No ethernet found.
</span></span><span style="display:flex;"><span>starting USB…
</span></span><span style="display:flex;"><span>USB0: Core Release: 2.80a
</span></span><span style="display:flex;"><span>scanning bus <span style="color:#f99b15">0</span> <span style="color:#815ba4">for</span> devices… <span style="color:#f99b15">4</span> USB Device<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> found
</span></span><span style="display:flex;"><span>scanning usb <span style="color:#815ba4">for</span> storage devices… <span style="color:#f99b15">1</span> Storage Device<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> found
</span></span><span style="display:flex;"><span>Hit any key to stop autoboot: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>U-Boot&gt; usb storage
</span></span><span style="display:flex;"><span>Device 0: Vendor: USB Rev: <span style="color:#f99b15">1100</span> Prod: Flash Disk
</span></span><span style="display:flex;"><span>Type: Removable Hard Disk
</span></span><span style="display:flex;"><span>Capacity: 30720.0 <span style="color:#ef6155">MB</span> <span style="color:#5bc4bf">=</span> 30.0 GB <span style="color:#5bc4bf">(</span><span style="color:#f99b15">62914560</span> x 512<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>U-Boot&gt; boot
</span></span><span style="display:flex;"><span>switch to partitions <span style="color:#776e71">#0, OK</span>
</span></span><span style="display:flex;"><span>mmc0 is current device
</span></span><span style="display:flex;"><span>Scanning mmc 0:1…
</span></span><span style="display:flex;"><span>Found EFI removable media binary efi/boot/bootaa64.efi
</span></span><span style="display:flex;"><span>Scanning disk mmc@7e202000.blk…
</span></span><span style="display:flex;"><span>Card did not respond to voltage <span style="color:#815ba4">select</span>!
</span></span><span style="display:flex;"><span>Scanning disk sdhci@7e300000.blk…
</span></span><span style="display:flex;"><span>Disk sdhci@7e300000.blk not ready
</span></span><span style="display:flex;"><span>Scanning disk usb_mass_storage.lun0…
</span></span><span style="display:flex;"><span>Found <span style="color:#f99b15">4</span> disks
</span></span><span style="display:flex;"><span><span style="color:#f99b15">82780</span> bytes read in <span style="color:#f99b15">12</span> ms <span style="color:#5bc4bf">(</span>6.6 MiB/s<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## Starting EFI application at 01000000 …</span>
</span></span><span style="display:flex;"><span>&gt;&gt; OpenBSD/arm64 BOOTAA64 0.11
</span></span><span style="display:flex;"><span>boot&gt;
</span></span><span style="display:flex;"><span>cannot open sd0a:/etc/random.seed: No such file or directory
</span></span><span style="display:flex;"><span>booting sd0a:/bsd: 2417208+377168+8373432-
</span></span><span style="display:flex;"><span>+732352 <span style="color:#5bc4bf">[</span>179732+96+291264+160768<span style="color:#5bc4bf">]=</span>0xf498
</span></span><span style="display:flex;"><span>f0
</span></span><span style="display:flex;"><span>type 0x0 pa 0x0 va 0x0 pages 0x1 attr 0x8
</span></span><span style="display:flex;"><span>type 0x7 pa 0x1000 va 0x0 pages 0x1ff attr 0x8
</span></span><span style="display:flex;"><span>type 0x2 pa 0x200000 va 0x200000 pages 0x4000 attr 0x8
</span></span><span style="display:flex;"><span>type 0x7 pa 0x4200000 va 0x0 pages 0x3e00 attr 0x8
</span></span><span style="display:flex;"><span>type 0x6 pa 0x8000000 va 0xe0250b000 pages 0x8 attr 0x8000000000000008
</span></span><span style="display:flex;"><span>type 0x7 pa 0x8009000 va 0x0 pages 0x312c0 attr 0x8
</span></span><span style="display:flex;"><span>type 0x2 pa 0x392c9000 va 0x392c9000 pages 0x4 attr 0x8
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>type 0x2 pa 0x39f41000 va 0x39f41000 pages 0x146a attr 0x8
</span></span><span style="display:flex;"><span>type 0x5 pa 0x3b3ab000 va 0xe358b6000 pages 0x1 attr 0x8000000000000008
</span></span><span style="display:flex;"><span>type 0x2 pa 0x3b3ac000 va 0x39f41000 pages 0x54 attr 0x8
</span></span><span style="display:flex;"><span>type 0xb pa 0x3f100000 va 0xe358b7000 pages 0x1 attr 0x8000000000000000
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1982, 1986, 1989, 1991, <span style="color:#f99b15">1993</span>
</span></span><span style="display:flex;"><span>The Regents of the University of California. All rights reserved.
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1995-2018 OpenBSD. All rights reserved. https://www.OpenBSD.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OpenBSD 6.3 <span style="color:#5bc4bf">(</span>RAMDISK<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#212: Sat Mar 24 20:24:43 MDT 2018</span>
</span></span><span style="display:flex;"><span>deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/RAMDISK
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">959180800</span> <span style="color:#5bc4bf">(</span>914MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">892710912</span> <span style="color:#5bc4bf">(</span>851MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>mainbus0 at root: Raspberry Pi <span style="color:#f99b15">3</span> Model B Rev 1.2
</span></span><span style="display:flex;"><span>cpu0 at mainbus0 mpidr 0: ARM Cortex-A53 r0p4
</span></span><span style="display:flex;"><span>efi0 at mainbus0: UEFI 2.7
</span></span><span style="display:flex;"><span>efi0: Das U-Boot rev 0x0
</span></span><span style="display:flex;"><span>simplefb0 at mainbus0: 656x416
</span></span><span style="display:flex;"><span>wsdisplay0 at simplefb0
</span></span><span style="display:flex;"><span>wsdisplay0: screen <span style="color:#f99b15">0</span> added <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>simplebus0 at mainbus0: <span style="color:#48b685">&#34;soc&#34;</span>
</span></span><span style="display:flex;"><span>bcmintc0 at simplebus0
</span></span><span style="display:flex;"><span>bcmdog0 at simplebus0
</span></span><span style="display:flex;"><span>bcmrng0 at simplebus0
</span></span><span style="display:flex;"><span>pluart0 at simplebus0
</span></span><span style="display:flex;"><span>bcmaux0 at simplebus0
</span></span><span style="display:flex;"><span>com0 at sim����: ns16550, no workingcom0: console
</span></span><span style="display:flex;"><span>dwctwo0 at simplebus0
</span></span><span style="display:flex;"><span>simplebus1 at mainbus0: <span style="color:#48b685">&#34;clocks&#34;</span>
</span></span><span style="display:flex;"><span>agtimer0 at mainbus0: tick rate <span style="color:#f99b15">19200</span> KHz
</span></span><span style="display:flex;"><span>usb0 at dwctwo0: USB revision 2.0
</span></span><span style="display:flex;"><span>uhub0 at usb0 configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Broadcom DWC2 root hub&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>uhub1 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Standard Microsystems product 0x9514&#34;</span> rev 2.00/2.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>smsc0 at uhub1 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Standard Microsystems SMSC9512/14&#34;</span> rev 2.00/2.00 addr <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>smsc0: address xx:xx:xx:xx:xx:xx
</span></span><span style="display:flex;"><span>ukphy0 at smsc0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x0001f0, model 0x000c
</span></span><span style="display:flex;"><span>umass0 at uhub1 port <span style="color:#f99b15">3</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;USB Flash Disk&#34;</span> rev 2.00/11.00 addr <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>umass0: using SCSI over Bulk-Only
</span></span><span style="display:flex;"><span>scsibus0 at umass0: <span style="color:#f99b15">2</span> targets, initiator <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>sd0 at scsibus0 targ <span style="color:#f99b15">1</span> lun 0: &lt;USB, Flash Disk, 1100&gt; SCSI2 0/direct removable serial.090c1000000000014806
</span></span><span style="display:flex;"><span>sd0: 30720MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">62914560</span> sectors
</span></span><span style="display:flex;"><span>bootfile: sd0a:/bsd
</span></span><span style="display:flex;"><span>boot device: sd0
</span></span><span style="display:flex;"><span>root on rd0a swap on rd0b dump on rd0b
</span></span><span style="display:flex;"><span>WARNING: CHECK AND RESET THE DATE!
</span></span><span style="display:flex;"><span>erase ^?, werase ^W, kill ^U, intr ^C, status ^T
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Welcome to the OpenBSD/arm64 6.3 installation program.
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>I<span style="color:#5bc4bf">)</span>nstall, <span style="color:#5bc4bf">(</span>U<span style="color:#5bc4bf">)</span>pgrade, <span style="color:#5bc4bf">(</span>A<span style="color:#5bc4bf">)</span>utoinstall or <span style="color:#5bc4bf">(</span>S<span style="color:#5bc4bf">)</span>hell? i
</span></span></code></pre></div><p>Procédez à l&rsquo;installation d&rsquo;OpenBSD. Ici, rien de spécial. La carte
réseau sera une <code>smsc0</code>  et peut utiliser DHCP. En utilisant -
&ldquo;Whole disk&rdquo; -  cela créera automatiquement et remplira une partition
MSDOS pour activer le démarrage depuis la clé USB. Au moment d&rsquo;écrire
cela, il n&rsquo;est pas possible d&rsquo;installer OpenBSD sur une microSD ; il
n&rsquo;y a pas de pilote pour cela. Je ne suis pas sûr, mais il semble
qu&rsquo;eMMC n&rsquo;est pas non plus supporté, pas encore. La seule manière
d&rsquo;installer OpenBSD est d&rsquo;utiliser un disque USB compatible pour démarrer.</p>
<p>Choisissez - &ldquo;Halt&rdquo; -  à la fin de l&rsquo;installation. Déconnectez
l&rsquo;alimentation USB. Enlevez la microSD d&rsquo;installation.</p>
<p>Reconnectez l&rsquo;alimention microUSB et regardez OpenBSD démarrer.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>U-Boot 2018.03 <span style="color:#5bc4bf">(</span>Mar <span style="color:#f99b15">20</span> <span style="color:#f99b15">2018</span> - 04:28:27 -0600<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DRAM:  <span style="color:#f99b15">948</span> MiB
</span></span><span style="display:flex;"><span>RPI <span style="color:#f99b15">3</span> Model B <span style="color:#5bc4bf">(</span>0xa02082<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>MMC:   mmc@7e202000: 0, sdhci@7e300000: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>Loading Environment from FAT… WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>Card did not respond to voltage <span style="color:#815ba4">select</span>!
</span></span><span style="display:flex;"><span>** Bad device mmc <span style="color:#f99b15">0</span> **
</span></span><span style="display:flex;"><span>Failed <span style="color:#5bc4bf">(</span>-5<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>In:    serial
</span></span><span style="display:flex;"><span>Out:   vidconsole
</span></span><span style="display:flex;"><span>Err:   vidconsole
</span></span><span style="display:flex;"><span>Net:   No ethernet found.
</span></span><span style="display:flex;"><span>starting USB…
</span></span><span style="display:flex;"><span>USB0:   Core Release: 2.80a
</span></span><span style="display:flex;"><span>scanning bus <span style="color:#f99b15">0</span> <span style="color:#815ba4">for</span> devices… <span style="color:#f99b15">4</span> USB Device<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> found
</span></span><span style="display:flex;"><span>       scanning usb <span style="color:#815ba4">for</span> storage devices… <span style="color:#f99b15">1</span> Storage Device<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> found
</span></span><span style="display:flex;"><span>Hit any key to stop autoboot:  <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>Card did not respond to voltage <span style="color:#815ba4">select</span>!
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Device 0: Vendor: USB      Rev: <span style="color:#f99b15">1100</span> Prod: Flash Disk
</span></span><span style="display:flex;"><span>            Type: Removable Hard Disk
</span></span><span style="display:flex;"><span>            Capacity: 30720.0 <span style="color:#ef6155">MB</span> <span style="color:#5bc4bf">=</span> 30.0 GB <span style="color:#5bc4bf">(</span><span style="color:#f99b15">62914560</span> x 512<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>… is now current device
</span></span><span style="display:flex;"><span>Scanning usb 0:1…
</span></span><span style="display:flex;"><span>Found EFI removable media binary efi/boot/bootaa64.efi
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>WARNING at /usr/obj/ports/u-boot-aarch64-2018.03-aarch64/u-boot-2018.03/drivers/mmc/bcm2835_sdhost.c:438/bcm2835_send_command<span style="color:#5bc4bf">()</span>!
</span></span><span style="display:flex;"><span>Card did not respond to voltage <span style="color:#815ba4">select</span>!
</span></span><span style="display:flex;"><span>Scanning disk mmc@7e202000.blk…
</span></span><span style="display:flex;"><span>Disk mmc@7e202000.blk not ready
</span></span><span style="display:flex;"><span>Card did not respond to voltage <span style="color:#815ba4">select</span>!
</span></span><span style="display:flex;"><span>Scanning disk sdhci@7e300000.blk…
</span></span><span style="display:flex;"><span>Disk sdhci@7e300000.blk not ready
</span></span><span style="display:flex;"><span>Scanning disk usb_mass_storage.lun0…
</span></span><span style="display:flex;"><span>Found <span style="color:#f99b15">3</span> disks
</span></span><span style="display:flex;"><span><span style="color:#f99b15">82780</span> bytes read in <span style="color:#f99b15">88</span> ms <span style="color:#5bc4bf">(</span><span style="color:#f99b15">918</span> KiB/s<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">## Starting EFI application at 01000000 …</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>3996244+595624+583064+805616 <span style="color:#5bc4bf">[</span>281462+96+464664/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>type 0x0 pa 0x0 va 0x0 pages 0x1 attr 0x8
</span></span><span style="display:flex;"><span>type 0x7 pa 0x1000 va 0x0 pages 0x1ff attr 0x8
</span></span><span style="display:flex;"><span>type 0x2 pa 0x200000 va 0x200000 pages 0x4000 attr 0x8
</span></span><span style="display:flex;"><span>type 0x7 pa 0x4200000 va 0x0 pages 0x3e00 attr 0x8
</span></span><span style="display:flex;"><span>type 0x6 pa 0x8000000 va 0x20987be000 pages 0x8 attr 0x8000000000000008
</span></span><span style="display:flex;"><span>type 0x7 pa 0x8009000 va 0x0 pages 0x317f6 attr 0x8
</span></span><span style="display:flex;"><span>type 0x2 pa 0x397ff000 va 0x397ff000 pages 0x4 attr 0x8
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>type 0x5 pa 0x3b3ab000 va 0x20cbb69000 pages 0x1 attr 0x8000000000000008
</span></span><span style="display:flex;"><span>type 0x2 pa 0x3b3ac000 va 0x39f41000 pages 0x54 attr 0x8
</span></span><span style="display:flex;"><span>type 0xb pa 0x3f100000 va 0x20cbb6a000 pages 0x1 attr 0x8000000000000000
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> using <span style="color:#f99b15">994392</span> bytes of bsd ELF symbol table <span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1982, 1986, 1989, 1991, <span style="color:#f99b15">1993</span>
</span></span><span style="display:flex;"><span>        The Regents of the University of California.  All rights reserved.
</span></span><span style="display:flex;"><span>Copyright <span style="color:#5bc4bf">(</span>c<span style="color:#5bc4bf">)</span> 1995-2018 OpenBSD. All rights reserved.  https://www.OpenBSD.org
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OpenBSD 6.3 <span style="color:#5bc4bf">(</span>GENERIC.MP<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#41: Sat Mar 24 20:06:13 MDT 2018</span>
</span></span><span style="display:flex;"><span>    deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span>  <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">964644864</span> <span style="color:#5bc4bf">(</span>919MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">905125888</span> <span style="color:#5bc4bf">(</span>863MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>mainbus0 at root: Raspberry Pi <span style="color:#f99b15">3</span> Model B Rev 1.2
</span></span><span style="display:flex;"><span>cpu0 at mainbus0 mpidr 0: ARM Cortex-A53 r0p4
</span></span><span style="display:flex;"><span>efi0 at mainbus0: UEFI 2.7
</span></span><span style="display:flex;"><span>efi0: Das U-Boot rev 0x0
</span></span><span style="display:flex;"><span>simplefb0 at mainbus0: 656x416
</span></span><span style="display:flex;"><span>wsdisplay0 at simplefb0 mux <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>wsdisplay0: screen 0-5 added <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>simplebus0 at mainbus0: <span style="color:#48b685">&#34;soc&#34;</span>
</span></span><span style="display:flex;"><span>bcmintc0 at simplebus0
</span></span><span style="display:flex;"><span>bcmdog0 at simplebus0
</span></span><span style="display:flex;"><span>bcmrng0 at simplebus0
</span></span><span style="display:flex;"><span>pluart0 at simplebus0
</span></span><span style="display:flex;"><span>bcmtemp0 at simplebus0
</span></span><span style="display:flex;"><span>bcmaux0 at simplebus0
</span></span><span style="display:flex;"><span>com0 at sim����: ns16550, no workingcom0: console
</span></span><span style="display:flex;"><span>dwctwo0 at simplebus0
</span></span><span style="display:flex;"><span>simplebus1 at mainbus0: <span style="color:#48b685">&#34;clocks&#34;</span>
</span></span><span style="display:flex;"><span>agtimer0 at mainbus0: tick rate <span style="color:#f99b15">19200</span> KHz
</span></span><span style="display:flex;"><span>cpu1 at mainbus0 mpidr 1: ARM Cortex-A53 r0p4
</span></span><span style="display:flex;"><span>cpu2 at mainbus0 mpidr 2: ARM Cortex-A53 r0p4
</span></span><span style="display:flex;"><span>cpu3 at mainbus0 mpidr 3: ARM Cortex-A53 r0p4
</span></span><span style="display:flex;"><span>usb0 at dwctwo0: USB revision 2.0
</span></span><span style="display:flex;"><span>uhub0 at usb0 configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Broadcom DWC2 root hub&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>uhub1 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Standard Microsystems product 0x9514&#34;</span> rev 2.00/2.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>smsc0 at uhub1 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Standard Microsystems SMSC9512/14&#34;</span> rev 2.00/2.00 addr <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>smsc0: address xx:xx:xx:xx:xx:xx
</span></span><span style="display:flex;"><span>ukphy0 at smsc0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x0001f0, model 0x000c
</span></span><span style="display:flex;"><span>umass0 at uhub1 port <span style="color:#f99b15">3</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;USB Flash Disk&#34;</span> rev 2.00/11.00 addr <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>umass0: using SCSI over Bulk-Only
</span></span><span style="display:flex;"><span>scsibus0 at umass0: <span style="color:#f99b15">2</span> targets, initiator <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>sd0 at scsibus0 targ <span style="color:#f99b15">1</span> lun 0: &lt;USB, Flash Disk, 1100&gt; SCSI2 0/direct removable serial.090c1000000000014806
</span></span><span style="display:flex;"><span>sd0: 30720MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">62914560</span> sectors
</span></span><span style="display:flex;"><span>vscsi0 at root
</span></span><span style="display:flex;"><span>scsibus1 at vscsi0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>softraid0 at root
</span></span><span style="display:flex;"><span>scsibus2 at softraid0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>bootfile: sd0a:/bsd
</span></span><span style="display:flex;"><span>boot device: sd0
</span></span><span style="display:flex;"><span>root on sd0a <span style="color:#5bc4bf">(</span>01654b77d1056385.a<span style="color:#5bc4bf">)</span> swap on sd0b dump on sd0b
</span></span><span style="display:flex;"><span>WARNING: CHECK AND RESET THE DATE!
</span></span><span style="display:flex;"><span>Automatic boot in progress: starting file system checks.
</span></span><span style="display:flex;"><span>/dev/sd0a <span style="color:#5bc4bf">(</span>01654b77d1056385.a<span style="color:#5bc4bf">)</span>: file system is clean; not checking
</span></span><span style="display:flex;"><span>setting tty flags
</span></span><span style="display:flex;"><span>pf enabled
</span></span><span style="display:flex;"><span>starting network
</span></span><span style="display:flex;"><span>smsc0: bound to 10.0.0.23 from 10.0.0.1 <span style="color:#5bc4bf">(</span>xx:xx:xx:xx:xx:xx<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>reordering libraries: <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>openssl: generating isakmpd/iked RSA keys… <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
</span></span><span style="display:flex;"><span>starting early daemons: syslogd pflogd ntpd.
</span></span><span style="display:flex;"><span>starting RPC daemons:.
</span></span><span style="display:flex;"><span>savecore: no core dump
</span></span><span style="display:flex;"><span>checking quotas: <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>clearing /tmp
</span></span><span style="display:flex;"><span>kern.securelevel: <span style="color:#f99b15">0</span> -&gt; <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>creating runtime link editor directory cache.
</span></span><span style="display:flex;"><span>preserving editor files.
</span></span><span style="display:flex;"><span>starting network daemons: sshd smtpd sndiod.
</span></span><span style="display:flex;"><span>running rc.firsttime
</span></span><span style="display:flex;"><span>Path to firmware: http://firmware.openbsd.org/firmware/6.3/
</span></span><span style="display:flex;"><span>No devices found which need firmware files to be downloaded.
</span></span><span style="display:flex;"><span>Checking <span style="color:#815ba4">for</span> available binary patches… <span style="color:#815ba4">done</span>.
</span></span><span style="display:flex;"><span>Run syspatch<span style="color:#5bc4bf">(</span>8<span style="color:#5bc4bf">)</span> to install:
</span></span><span style="display:flex;"><span>001_perl
</span></span><span style="display:flex;"><span>002_libtls
</span></span><span style="display:flex;"><span>003_arp
</span></span><span style="display:flex;"><span>004_gif
</span></span><span style="display:flex;"><span>005_httpd
</span></span><span style="display:flex;"><span>006_ipseclen
</span></span><span style="display:flex;"><span>007_libcrypto
</span></span><span style="display:flex;"><span>008_ipsecout
</span></span><span style="display:flex;"><span>009_libcrypto
</span></span><span style="display:flex;"><span>011_perl
</span></span><span style="display:flex;"><span>starting local daemons: cron.
</span></span><span style="display:flex;"><span>Sun Mar <span style="color:#f99b15">25</span> 07:56:40 CEST <span style="color:#f99b15">2018</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>OpenBSD/arm64 <span style="color:#5bc4bf">(</span>bagheera.tumfatig.net<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">(</span>console<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>login: root
</span></span><span style="display:flex;"><span>Password:
</span></span><span style="display:flex;"><span>OpenBSD 6.3 <span style="color:#5bc4bf">(</span>GENERIC.MP<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#41: Sat Mar 24 20:06:13 MDT 2018</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Welcome to OpenBSD: The proactively secure Unix-like operating system.
</span></span></code></pre></div><p>Et voilà ! Rien de bien difficile.</p>
<hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Joel Carnat !</p>
<p><em>Cette page est la traduction de la page <a href="https://www.tumfatig.net/20180706/running-openbsd-on-raspberry-pi-3/" rel="external">Running OpenBSD on Raspberry Pi 3</a>
du site TUM&rsquo;FATIG. - <a href="https://www.tumfatig.net/disclaimer/" rel="external">licence de type BSD</a></em>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;Running OpenBSD on Raspberry Pi 3&#39; de l&#39;auteur Joel Carnat]]></summary>
        <published>2018-10-09T11:37:46+02:00</published>
        <updated>2023-07-25T18:11:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f25ae0fa-b097-cc6b-1f0c-c1fb2e9ec65f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/minidlna/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MiniDLNA (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="MiniDLNA" scheme="http://doc.huc.fr.eu.org/fr/tags/minidlna/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>MiniDLNA</strong> est un simple logiciel de serveur multimédia, écrit en C, dont le
but est d&rsquo;être totalement compatible avec différents clients 














<span lang="en">DLNA <em>(Digital Living Network Alliance)</em></span>

































































































et/ou 






































































































<span lang="en">UPnP-AV <em>(Universal Plug and Play - Audio Video)</em></span>








, tels que des téléviseurs, tablettes et autres
médiums…</p>
<ul>
<li>Site web : <a href="http://sourceforge.net/projects/minidlna/" rel="external">http://sourceforge.net/projects/minidlna/</a></li>
<li>Version installée : <strong>1.2.1p1</strong></li>
<li>OS : <strong>OpenBSD 6.3</strong></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Cette solution sous OpenBSD n&rsquo;est pas satisfaisante ; malheureusement, il vaut
mieux se tourner vers un autre OS qui la fait fonctionner sans soucis, voire un
autre logiciel</p>
<p><abbr lang="en" title="Digital Living Network Alliance">DLNA</abbr></p>
<p>.</p>
</div>

<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>minidlna</strong>.</p>
<p>Un utilisateur <code>_minidlna</code> sans droit système est créé !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>ATTENTION à ne jamais exécuter le binaire <code>minidlnad</code> avec les droits <code>root</code>… <br>
celui-ci mettra ses droits sur le répertoire de la base de données de minidlna.</p>
<p>Résultat, lors de l&rsquo;exécution du service <strong>minidlna</strong> par l&rsquo;outil <code>rcctl</code>,
celui-ci échouerait - il faudra réattribuer les droits de l&rsquo;utilisateur
<code>_minidlna</code> sur le répertoire de la db, à coup de <code>chown -R _minidlna /dir/db</code> !</p>
</div>

<h2 id="configuration">Configuration</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">L&rsquo;option <code>inotify</code> ne fonctionne pas sous OpenBSD !</div>

<h4 id="fichier-de-configuration">Fichier de configuration</h4>
<p>La configuration du fichier <code>/etc/minidlna.conf</code> n&rsquo;est pas complexe en
soi - si vous ne spécifiez aucune option, ce sont les valeurs par défaut
qui sont prises en charge.</p>
<p>Le port de connexion au service, par défaut, est le <code>8200</code>.</p>
<p>Veillez néanmoins à configurer les répertoires à scanner <code>media_dir</code>,
en faisant attention à ces options, avec une virgule séparant l&rsquo;option
et le répertoire cible :</p>
<ul>
<li><code>A</code> pour le contenu audio</li>
<li><code>P</code> pour les images - <em>(P pour <strong>pictures</strong>, en anglais)</em></li>
<li><code>V</code> pour les vidéos</li>
<li>et, <code>PV</code> pour le contenu rassemblant et les images et les vidéos.</li>
</ul>
<p>Profitez-en pour lui donner à votre service un joli petit nom, avec
l&rsquo;option <code>friendly_name</code></p>
<p>Activez l&rsquo;option tivo : <code>enable_tivo=yes</code> - <span class="red">Attention, cette
option nécessite que le service de recherche <a href="https://wiki.openbsd.fr.eu.org/doku.php/system/net/avahi" rel="external">Avahi</a> soit fonctionnel !</span></p>
<p>Une option intéressante est de limiter le nombre de connexion simultanée : <code>max_connections</code></p>
<h2 id="démarrer-minidlna">Démarrer MiniDLNA</h2>
<p>Une fois le fichier configuré, il ne vous reste plus qu&rsquo;à :</p>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer le service</a>
 <code>minidlna</code></li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#param%c3%a9trer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Paramétrer</a>
 le drapeau <code>-R</code></li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Démarrer le service</a>
 <code>minidlna</code></li>
</ul>
<h2 id="règles-pf">Règles PF</h2>
<p>La configuration des règles du pare-feu 







































































<span lang="en">PF <em>(Packet Filter)</em></span>







































 est un peu plus délicate.
En effet, il est nécessaire de ne pas filtrer le flux mdns, et d&rsquo;ouvrir les ports
adéquates :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">dlna_port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;8200&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block log pass out</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># minidlna</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto tcp from egress:network to egress port $dlna_port flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto udp from egress:network to egress port $dlna_port allow-opts keep state</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># avahi multicast traffic</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># règle par défaut, présentée dans la documentation *pkg_readme* d&#39;avahi…</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on egress inet proto udp from any to 224.0.0.251 port mdns allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># règle IPv6 équivalente à la précédente</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on egress inet6 proto udp from any to ff02::fb port mdns allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># règles SSDP nécessaire</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on egress inet proto udp from any to 239.255.255.250 port 1900 allow-opts</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass on egress inet6 proto udp from any to { ff02::c, ff05::c, ff08::c } port 1900 allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/rcctl.8" title="Page du Manuel OpenBSD pour : rcctl">rcctl(8)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installer et configurer le serveur MiniDLNA sous OpenBSD : serveur multimédia DLNA et UPNP-AV]]></summary>
        <published>2018-10-08T14:11:45+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:54200046-343f-8cea-7090-e901dbbcfe7f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/deluge-torrent/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Service Deluge (torrent)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Deluge" scheme="http://doc.huc.fr.eu.org/fr/tags/deluge/" />
        <category term="Torrent" scheme="http://doc.huc.fr.eu.org/fr/tags/torrent/" />
        <category term="client" scheme="http://doc.huc.fr.eu.org/fr/tags/client/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="présentation">Présentation</h2>
<p>Deluge est un client BitTorrent léger, logiciel libre et multiplate-forme.</p>
<p>Déluge contient les fonctionnalités communes aux clients BitTorrent telles que
chiffrement de protocole, 















































































































, découverte entre homologues locaux
<em>(LSD)</em>, échange entre homologues <em>(






































































<span lang="en">PEX <em>(Peer EXchange)</em></span>








































)</em>, 





































































































<span lang="en">UPnP <em>(Universal Plug and Play)</em></span>









,





























































<span lang="en">NAT-PMP <em>(NAT Port Mapping Protocol)</em></span>


















































, prise en charge du proxy, ressources Web, limites de
vitesse globales et
par torrent.</p>
<p>Deluge a été conçu pour fonctionner à la fois comme une application
autonome normale et en tant que client-serveur. Dans le modèle de client
léger, un démon Deluge gère toute l&rsquo;activité de BitTorrent et peut
fonctionner sur des machines sans et avec interfaces utilisateur
permettant de se connecter à distance depuis n&rsquo;importe quelle autre
plateforme.</p>
<ul>
<li>Site web : <a href="https://www.deluge-torrent.org" rel="external">https://www.deluge-torrent.org</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Depuis la version d&rsquo;OpenBSD 6.3, deluge-torrent est intégré en tant que
paquet - ce qui installe toutes les dépendances nécessaires.</p>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 <strong>deluge</strong>.</p>
<p>Néanmoins, il y a quelques étapes supplémentaires à franchir !</p>
<h2 id="configuration">Configuration</h2>
<h3 id="étape-1--création-utilisateur-dédié">Étape 1 : création utilisateur dédié</h3>
<ul>
<li>Créer un utilisateur dédié <code>_deluge</code>, sans droit particulier,
sans shell <code>nologin</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ userinfo _deluge
</span></span><span style="display:flex;"><span>login   _deluge
</span></span><span style="display:flex;"><span>passwd  *
</span></span><span style="display:flex;"><span>uid     <span style="color:#f99b15">706</span>
</span></span><span style="display:flex;"><span>groups  _deluge
</span></span><span style="display:flex;"><span>change  NEVER
</span></span><span style="display:flex;"><span>class
</span></span><span style="display:flex;"><span>gecos   deluge user
</span></span><span style="display:flex;"><span>dir     /home/_deluge
</span></span><span style="display:flex;"><span>shell   /sbin/nologin
</span></span><span style="display:flex;"><span>expire  NEVER
</span></span></code></pre></div><h3 id="étape-2--création-fichier-rc">Étape 2 : création fichier rc</h3>
<ul>
<li>Créer un fichier rc dédié au binaire <code>deluged</code>, tel que <code>/etc/rc.d/deluged</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: deluge,v 1.3.15 2018/10/19 19:05:00 Stephane HUC $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/usr/local/bin/deluged&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#daemon_flags=&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon_user</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;_deluge&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">. /etc/rc.d/rc.subr</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_reload</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">NO</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_cmd $1</span>
</span></span></code></pre></div><p>Ensuite, donnez-lui les droits d&rsquo;exécution nécessaire : <br>
<code>:# chmod 0755 /etc/rc.d/deluged</code></p>
<p>Ce script permet à minima de démarrer le service : <code># rcctl start deluged</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention, pour une raison que je ne connais pas encore, je n&rsquo;arrive pas à
gérer l&rsquo;arrêt du service !</div>

<h3 id="étape-3--règles-pf">Étape 3 : règles PF</h3>
<p>En admettant que vos règles bloquent tout ce qui doit être bloqué, et
laissent passer les connexions entrantes et sortantes, relatives au flux
déjà établis, quelques règles de cet acabit permettent de s&rsquo;assurer
d&rsquo;un minima :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">deluge_web_port</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;8112&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">p2p_in_ports</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;6881:6891&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;t_admins&gt; const { addr_ip_votre_station }</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">block log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto tcp from &lt;t_admins&gt; to egress port $deluge_web_port flags S/SA modulate state</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in quick on egress proto udp from any to egress port $p2p_in_ports allow-opts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass out on egress inet proto tcp from egress $flag $st_mod user _deluge</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(…)</span>
</span></span></code></pre></div><ul>
<li>
<p>La règle sortante semble nécessaire pour laisser sortir &ldquo;tranquillement&rdquo; tout
le flux sortant TCP… cela permet d&rsquo;interroger les différents trackers, mais
aussi le flux de connexion vers les différents clients…</p>
</li>
<li>
<p>l&rsquo;option <code>user _deluge</code> est seulement pour &ldquo;obliger&rdquo; que ce flux lui appartiennent -
tout autre flux TCP qui ne viendrait pas de lui serait bloqué !
<em>(c&rsquo;est un pis-aller…)</em></p>
</li>
</ul>
<hr>
<h2 id="pour-finir">Pour finir</h2>
<p>Il ne vous reste plus qu&rsquo;à exécuter le binaire <code>deluge-web</code> avec un autre utilisateur…</p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment faire fonctionner le client BitTorent nommé Deluge sous OpenBSD]]></summary>
        <published>2018-10-07T14:46:44+01:00</published>
        <updated>2020-05-21T14:30:40+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ae180509-ab66-6029-d7dd-e63527127a52</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/mount-crypt-hd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : monter un disque dur chiffré automatiquement</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="mount" scheme="http://doc.huc.fr.eu.org/fr/tags/mount/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Non, je ne vais pas vous apprendre à créer un disque dur chiffré sous
OpenBSD - la <a href="https://www.openbsd.org/faq/faq14.html#softraidFDE" rel="external">FAQ officielle</a> <em>(en anglais)</em> vous l&rsquo;apprendra mieux que
moi-même !</p>
<h3 id="convention-et-étapes-de-base">Convention et étapes de base</h3>
<p>Vous vous êtes assuré que le disque dur est connecté… électriquement, et soit en
USB, en SATA, etc… Admettons que celui-ci soit reconnu par le système en tant que
<em>sd0</em>.</p>
<p><strong>L&rsquo;étape 0</strong> - de base - est d&rsquo;<strong>enregistrer la passphrase dans un fichier</strong>,
et de lui donner les droits nécessaires au bon fonctionnement de <code>bioctl</code> : <code>0600</code>.</p>
<p>Par convention, nous appellerons ce fichier <code>/root/crypt_passwd</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">disk</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;sd0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">file_passwd</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/root/crypt_passwd&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">file_tmp</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/tmp/raid.info&#34;</span>
</span></span></code></pre></div><p>Une méthode plus sûre est l&rsquo;usage d&rsquo;une clé USB dédié au déchiffrement. <br>
À savoir qu&rsquo;il est possible d&rsquo;utiliser une seule et même clé pour le chiffrement
de plusieurs disques, une partition par chiffrement.</p>
<h3 id="duid">duid</h3>
<p>La première étape est d&rsquo;obtenir le <code>duid</code> - <em>c&rsquo;est l&rsquo;identifiant du disk, fourni
par disklabel</em> - relatif à notre périphérique <code>sd0</code>.</p>
<p><code>duid=&quot;$(disklabel ${disk0} | awk -F':' '/duid/ { gsub(/[[:space:]]*/, &quot;&quot;, $2) ; printf &quot;%s&quot;,$2 }')&quot;</code></p>
<p>Que fait <code>awk</code> dans les détails ? <br>
Il recherche la ligne comportant la mention <code>duid</code>, et supprime tout espace,
pour enfin afficher le résultat recherché, sans retour à la ligne !</p>
<h3 id="numéro-partition-raid">numéro partition RAID</h3>
<p>Obtenons la lettre de partition relative à la partition RAID - <strong>en réalité, la
partition chiffrée par <em>bioctl</em></strong>.</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">:# get partition&#39;s letter
s=&#34;$(disklabel ${disk} | awk -F&#39;:&#39; &#39;/RAID/ { gsub(/[[:space:]]*/, &#34;&#34;, $1); printf &#34;%s&#34;,$1 }&#39; )&#34;
slide=&#34;${duid}.$s&#34;
</code></pre><h3 id="identifiant-disque">identifiant disque</h3>
<p>Attachons le périphérique chiffré à un périphérique softraid0 :</p>
<p><code>bioctl -c C -l ${slide} -p ${file_passwd} softraid0 &gt; ${file_tmp}</code></p>
<p>Le fichier temporaire contiendra très certainement une mention, telle que la
suivante : <em>softraid0: CRYPTO volume attached as sd2</em> - <br>
néanmoins cela dépend du fait d&rsquo;avoir d&rsquo;autres périphériques connectés, soit sur
les ports SATA, USB, etc…</p>
<p>De toute façon, quelque soit l&rsquo;écriture restituée dans le fichier temporaire,
nous récupérerons l&rsquo;identifiant du périphérique attaché, de manière &quot;dynamique&quot;.</p>
<p><code>device=&quot;$(awk '/CRYPTO/ { printf &quot;%s&quot;,$6 }' ${file_tmp})&quot;</code></p>
<p>Dans cet exemple, la valeur obtenue sera <code>sd2</code>.</p>
<p>Maintenant, obtenons à nouveau la lettre de partition, mais cette fois-ci du
périphérique attaché, pour construire les variables nécessaires :</p>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">s=&#34;$(disklabel ${device} | awk -F&#39;:&#39; &#39;/&#39;4.2BSD/ { gsub(/[[:space:]]*/, &#34;&#34;, $1); printf &#34;%s&#34;,$1 }&#39; )&#34;

partition=&#34;${disk}$s&#34;
slide=&#34;${duid}.$s&#34;
</code></pre><h3 id="mount">mount</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mkdir -p /mnt/<span style="color:#f99b15">${</span><span style="color:#ef6155">device</span><span style="color:#f99b15">}</span>
</span></span><span style="display:flex;"><span>mount -o noatime,nodev,noexec,nosuid,rw,softdep /dev/<span style="color:#f99b15">${</span><span style="color:#ef6155">partition</span><span style="color:#f99b15">}</span> /mnt/<span style="color:#f99b15">${</span><span style="color:#ef6155">device</span><span style="color:#f99b15">}</span>
</span></span></code></pre></div><p>Voilà, normalement nous avons accès au périphérique chiffré attaché et monté !</p>
<p>Il n&rsquo;y a plus qu&rsquo;à le remplir…</p>
<h4 id="fs-check">FS check</h4>
<p>Si le montage ne se fait pas correctement, exécutons une vérification du
système de fichier :</p>
<p><code>fsck -y /dev/${partition}</code></p>
<p>Si c&rsquo;est OK, essayez de remonter la partition vers le répertoire choisi, avec
la commande <code>mount</code> ci-dessus.</p>
<h3 id="umount">umount</h3>
<p>Le démontage et le détachement du périphérique se fait très simplement :</p>
<p><code>umount -f /mnt/${device}</code> <code>bioctl -d ${device}</code></p>
<p>Pense-bête pour supprimer le fichier temporaire qui n&rsquo;est plus
nécessaire :</p>
<p><code>rm -fP &quot;${file_tmp}&quot;</code></p>
<h3 id="tldr">TL;DR</h3>
<p>Voici le script complet, dont je me sers, pour monter et démonter automatique
un périphérique chiffré avec <em>bioctl</em> dès le démarrage du système OpenBSD.</p>
<p>Il faut l&rsquo;utiliser ainsi :</p>
<ul>
<li>
<p>pour monter le périphérique : <code>./mount_crypt_hd mount</code> - créez le fichier
<code>/etc/rc.local</code> et appelez le script de la manière à le monter…</p>
</li>
<li>
<p>pour démonter le périphérique proprement : <code>./mount_crypt_hd umount</code> - créez
le fichier <code>/etc/rc.shutdown</code> et appelez le script de la manière à le démonter…</p>
</li>
</ul>
<pre tabindex="0"><code class="language-pdksh" data-lang="pdksh">#!/bin/sh
#set -x

###
#
# Author: Stéphane HUC
# mail: devs@stephane-huc.net
# gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58
#
# License: BSD Simplified
#
# Github:
#
# Date: 2018/10/03
#
###

error=0 # DO NOT TOUCH
device=&#34;&#34;  # DO NOT TOUCH
dir_nas=&#34;/mnt/nas&#34;  # mount point of crypted hd
disk0=&#34;sd0&#34; # DO NOT TOUCH
file_passwd=&#34;/root/nas&#34; # passwd file of crypted hd
partition=&#34;&#34;    # DO NOT TOUCH
s=&#34;&#34;    # letter of slide - DO NOT TOUCH
slide=&#34;&#34;    # DO NOT TOUCH

################################################################################
###
##
#   FUNCTIONS
##
###
################################################################################
get_device() {
    device=&#34;$(awk &#39;/CRYPTO/ { printf &#34;%s&#34;,$6 }&#39; ${file_tmp})&#34;
}

get_duid() {
    # get duid info
    duid=&#34;$(disklabel ${disk0} | awk -F&#39;:&#39; &#39;/duid/ { gsub(/[[:space:]]*/, &#34;&#34;, $2) ; printf &#34;%s&#34;,$2 }&#39;)&#34;
}

get_slide() {
    disk=&#34;$1&#34;
    case &#34;${disk}&#34; in
        ${disk0}) pattern=&#34;RAID&#34; ;;
        ${device}) pattern=&#34;4.2BSD&#34; ;;
    esac

    # get partition&#39;s letter
    s=&#34;$(disklabel ${disk} | awk -F&#39;:&#39; &#39;/&#39;${pattern}&#39;/ { gsub(/[[:space:]]*/, &#34;&#34;, $1); printf &#34;%s&#34;,$1 }&#39; )&#34;

    partition=&#34;${disk}$s&#34;
    slide=&#34;${duid}.$s&#34;

    unset disk pattern
}

_mount() {
    [ ! -d ${dir_nas} ] &amp;&amp; mkdir -p &#34;${dir_nas}&#34;
    logger &#34;rc.local: mount ${partition} to ${dir_nas}!&#34;
    mount -o noatime,nodev,noexec,nosuid,rw,softdep /dev/${partition} ${dir_nas}
}

mount_crypt_device() {
    get_duid
    get_slide ${disk0}

    file_tmp=&#34;/tmp/${duid}.info&#34;

    if [ -n ${duid} ]; then
        # attempt to open HD
        logger &#34;rc.local: bioctl -c C -l ${slide} -p ${file_passwd} &#34;
        if bioctl -c C -l ${slide} -p ${file_passwd} softraid0 &gt; ${file_tmp}; then
            get_device
            echo &#34;*** bioctl attaches from ${slide} to /dev/${device}: OK!&#34;
            chmod 0400 ${file_tmp}

        else
            echo &#34;*** bioctl C from ${slide}: KO!&#34;

        fi

        if [ -r ${file_tmp} ]; then
            get_slide ${device}

            if [ -n ${device} ]; then
                # attempt to mount
                if _mount; then
                    echo &#34;*** Mount ${device} on ${dir_nas}: OK!&#34;

                else
                    error=1
                    echo &#34;*** Mount ${device}: KO!&#34;
                    echo &#34;*** Init a FS check on ${partition}!&#34;
                    logger &#34;rc.local: Can&#39;t mount ${device}; attempt FS check on ${partition}!&#34;

                    if fsck -y /dev/${partition}; then
                        echo &#34;*** Fsck seems: OK!&#34;
                        logger &#34;rc.local: FS check on ${partition}: OK!&#34;

                        if _mount; then error=0; fi

                    else
                        echo &#34;*** Fsck seems: KO!&#34;
                        echo &#34;### Can not mount on ${device} crypted HD ${slide}! ###&#34;
                        logger &#34;rc.local: FS check on ${device}: KO! Can&#39;t mount-it!&#34;

                    fi

                fi

                if [ ${error} -eq 0 ]; then sync; fi

            fi

        fi

}

_shutdown() {
    get_duid
    file_tmp=&#34;/tmp/${duid}.info&#34;
    get_device
    logger &#34;rc.shutdown: umount:${dir_nas}&#34;
    umount -f &#34;${dir_nas}&#34;
    sleep 3
    sync
    logger &#34;rc.shutdown: bioctl -d ${device}&#34;
    bioctl -d ${device}
    rm -fP &#34;${file_tmp}&#34;
}

################################################################################
###
##
#   EXECUTION
##
###
################################################################################

case &#34;$1&#34; in
    &#34;mount&#34;) mount_crypt_device ;;
    &#34;umount&#34;) _shutdown ;;
esac
</code></pre><h2 id="remerciement">Remerciement</h2>
<ul>
<li><em><a href="http://www.vincentdelft.be/post/post_20160719" rel="external">source</a> - en anglais</em></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment monter automatiquement un disque dur FFS chiffré sous OpenBSD ?]]></summary>
        <published>2018-10-03T23:41:58+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8906621b-fae3-7009-4975-50b587f2785b</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/tumfatig.net/telegraf-openbsd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Exécuter Telegraf sur OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Telegraf" scheme="http://doc.huc.fr.eu.org/fr/tags/telegraf/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article &ldquo;<strong><a href="https://www.tumfatig.net/2018/running-telegraf-on-openbsd/" rel="external">Running Telegraf on OpenBSD</a></strong>&rdquo;,
écrit par Joel Carnat.</p>
<hr>
<h1 id="exécuter-telegraf-sur-openbsd">Exécuter Telegraf sur OpenBSD</h1>
<ul>
<li>OS concerné : <strong>6.3 et &gt;</strong></li>
</ul>
<hr>
<p>J&rsquo;ai essayé d&rsquo;exécuter Telegraf d&rsquo;InfluxData sur la version 6.2
d&rsquo;OpenBSD mais il n&rsquo;était pas disponible dans les ports et n&rsquo;ai pas été
capable de le compiler depuis les sources. Mais cela a changé puisque
j&rsquo;ai pu faire fonctionner une instance dans OpenBSD 6.3. Voici comment
le compiler et exécuter Telegraf sur OpenBSD.</p>
<p>Utilisez OpenBSD 6.3, architecture amd64. Il peut peut-être fonctionner
sur d&rsquo;autres architectures et versions.</p>
<p>Installez les outils de développement requis :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add gmake git go</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>gmake-4.2.1: ok
</span></span><span style="display:flex;"><span>git-2.16.2: ok
</span></span><span style="display:flex;"><span>go-1.10: ok
</span></span></code></pre></div><p>Configurez l&rsquo;environnement de compilation :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># export GOPATH=~/go</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># export PATH=$PATH:~/go/bin</span>
</span></span></code></pre></div><p>Démarrez la compilation de l&rsquo;outil de gestion des dépendances du langage
Go :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># go get github.com/golang/dep</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># cd $GOPATH/src/github.com/golang/dep</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># go install ./...</span>
</span></span></code></pre></div><p>Ensuite, compilez Telegraf, lui-même :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># go get github.com/influxdata/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># cd $GOPATH/src/github.com/influxdata/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># gmake</span>
</span></span><span style="display:flex;"><span>dep ensure -vendor-only
</span></span><span style="display:flex;"><span>go build -ldflags <span style="color:#48b685">&#34; -X main.commit=c7e2945a -X main.branch=master&#34;</span> ./cmd/telegraf
</span></span></code></pre></div><p>Cela compilera la branche master. On devrait être capable de compiler
une branche stable en utilisant les bascules et les étiquettes de Git.
Je n&rsquo;ai pas pu compiler la version 1.7.4.</p>
<p>Quand le binaire est prêt, installez-le :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># gmake install</span>
</span></span><span style="display:flex;"><span>go build -ldflags <span style="color:#48b685">&#34; -X main.commit=c7e2945a -X main.branch=master&#34;</span> ./cmd/telegraf
</span></span><span style="display:flex;"><span>mkdir -p /usr/local/bin/
</span></span><span style="display:flex;"><span>cp telegraf /usr/local/bin/
</span></span></code></pre></div><p>J&rsquo;utilise les fonctions de Classes et Utilisateurs d&rsquo;OpenBSD, ainsi
Telegraf ne sera pas exécuté avec les droits root :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># vim /etc/login.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(...)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">telegraf:\</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">:tc</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">daemon:</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># cap_mkdb /etc/login.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># groupadd -g xxxx _telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># useradd -u xxxx -g xxxx -c &#34;Telegraf agent&#34; -d /var/telegraf -s /sbin/nologin -L telegraf _telegraf</span>
</span></span></code></pre></div><p>Le fichier de configuration par défaut sera dans <code>/etc</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># mkdir /etc/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chown _telegraf:_telegraf /etc/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chmod 0750 /etc/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># doas -u _telegraf telegraf config &gt; /etc/telegraf/telegraf.conf</span>
</span></span></code></pre></div><p>Finalement, il faut créer un script <code>rc.d</code> pour faciliter la gestion :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># cat &gt; /etc/rc.d/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#!/bin/ksh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Start InfluxData Telegraf agent</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/usr/local/bin/telegraf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon_flags</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;--config /etc/telegraf/telegraf.conf&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon_user</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;_telegraf&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">. /etc/rc.d/rc.subr</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pexp</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;.*telegraf&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_reload</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">NO</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_pre() {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/bin/install -d -o _telegraf -g _telegraf -m 0750 /var/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_cmd $1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#EOF</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chmod 0755 /etc/rc.d/telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># chown root:wheel /etc/rc.d/telegraf</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable telegraf</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start telegraf</span>
</span></span></code></pre></div><p>Il y a un problème avec la fonction rc_check() lors de l&rsquo;utilisation de
<code>start</code> ou <code>restart</code>. Je n&rsquo;ai pas pu trouver pourquoi. Selon
`/etc/rc.d/rc.subr” : “(…) # XXX for unknown reason, rc_check can fail (…)”.</p>
<p>Jusque là, Telegraf exécute les filtres d&rsquo;entrée d&rsquo;Apache, MySQL,
PHP-FPM et SNMP et le filtre de sortie d&rsquo;InfluxDB. Et, il ne semble pas
utiliser plus de ressources que Collectd.</p>
<hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Joel Carnat !</p>
<p><em>Cette page est la traduction de la page <a href="https://www.tumfatig.net/2018/running-telegraf-on-openbsd/" rel="external">Running Telegraf on OpenBSD</a>
du site TUM&rsquo;FATIG. - <a href="https://www.tumfatig.net/disclaimer/" rel="external">licence de type BSD</a></em>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;Running Telegraf on OpenBSD&#39; de l&#39;auteur Joel Carnat]]></summary>
        <published>2018-09-09T11:55:02+02:00</published>
        <updated>2023-05-09T14:02:04+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:feb3023b-84ce-8315-8d24-369db56f8770</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/jcs.org/openbsd-surface-go/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD sur la Surface Go de Microsoft</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Surface" scheme="http://doc.huc.fr.eu.org/fr/tags/surface/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Pour une raison quelconque, j&rsquo;aime les petits ordinateurs portables et
les contraintes qu&rsquo;ils imposent (tant qu&rsquo;ils sont encore utilisables).
J&rsquo;ai utilisé un <a href="https://jcs.org/notaweblog/2009/04/23/on_the_dell_mini_9" rel="external">Dell Mini 9</a>
pendant des jours et j&rsquo;utilisais jusqu&rsquo;à récemment un MacBook Air 11&quot;
comme principale machine de développement, et ce  pendant de nombreuses
années.
Récemment, Microsoft a annoncé une version plus petite et moins chère de
ses tablettes Surface, appelées <a href="https://www.microsoft.com/en-us/p/surface-go/8v9dp4lnknsz" rel="external">Surface Go</a>,
qui ont éveillé mon intérêt.</p>
<figure>
    <a href="/images/jcs.org/2018-08-31-surface_go-680x224.jpg" title="Présentation de la Surface Go de Microsoft">
    <picture>
        
        <source srcset="/images/jcs.org/2018-08-31-surface_go-680x224_hu_cb358d5b333631b4.webp" type="image/webp">
        
        <img alt="Présentation de la Surface Go de Microsoft" height="82" loading="lazy" src="/images/jcs.org/2018-08-31-surface_go-680x224_hu_b610304f00830802.jpg" type="image/jpeg" width="250">
    </picture>
    </a>
    <figcaption>Présentation de la Surface Go de Microsoft</figcaption>
</figure>
<h2 id="matériel">Matériel</h2>
<p>La Surface Go est disponible dans deux configurations matérielles :</p>
<ul>
<li>une avec 4 Go de RAM et un disque eMMC de 64 Go,</li>
<li>et une autre avec 8 Go de RAM avec un disque SSD NVMe de 128 Go.
(J&rsquo;ai pris cette dernière).</li>
</ul>
<p>Les deux sont livrées avec un processeur Intel Pentium Gold 4415Y qui
n&rsquo;est pas très rapide, mais reste certainement utilisable.</p>
<p>La tablette mesure 23,5 cm de long, ~ 17.5 cm de large, ~ 0.8 cm
d&rsquo;épaisseur. Elle a un écran tactile de 10&quot; de diagonale (3:2),
recouvert d&rsquo;un Gorilla Glass et une résolution de 1800x1200.
Le pourtour est assez large, spécialement pour un si petit écran, mais
cela a du sens sur un périphérique qui est destiné à être tenu, pour
éviter les appuis accidentels sur l&rsquo;écran.</p>
<p>Le clavier et le pavé tactile sont situés sur une dalle amovible distincte,
appelée Surface Signature Type Cover, vendue séparément.  J&rsquo;ai opté pour
la couverture &ldquo;bleu de cobalt&rdquo; qui contient un matériau en alcantara doux,
semblable à un tissu.
Le couvercle se fixe magnétiquement le long du bord inférieur de
l&rsquo;appareil et présente des claviers et des pavés tactiles reliés par USB.
Lorsque le capot est replié contre l&rsquo;écran, il envoie un signal de veille
ACPI et est maintenu magnétiquement sur l&rsquo;écran. En utilisation normale,
le couvercle peut être placé à plat sur une surface ou légèrement relevé
d’environ 3/4, près de l’écran pour une meilleure ergonomie. Lorsque vous
utilisez l’appareil comme une tablette, vous pouvez faire pivoter le
couvercle derrière ce qui arrête automatiquement l&rsquo;envoi des événements
clavier et pavé tactile jusqu&rsquo;à ce qu&rsquo;il soit à nouveau retourné.</p>
<p>Le clavier a une bonne quantité de touches et une bonne disposition,
avec <kbd>Home</kbd> / <kbd>Fin</kbd> / <kbd>Page Up</kbd> / <kbd>Page Down</kbd>
accessible via <kbd>Fn</kbd> + <kbd>Gauche</kbd> / <kbd>Droite</kbd> / <kbd>Haut</kbd> / <kbd>Bas</kbd>,
mais aussi les touches <kbd>Home</kbd> / <kbd>Fin</kbd> / <kbd>Page Up</kbd> / <kbd>Page Down</kbd>
dédiées. Je trouve les touches <kbd>F9</kbd> à <kbd>F12</kbd> assez
utiles puisque la disposition du clavier est un peu petite. Par défaut,
les touches <kbd>F1</kbd> à <kbd>F12</kbd> n&rsquo;envoient pas les codes de
touches F1-F12, la touche <kbd>Fn</kbd> doit être utilisée, soit
enfoncée temporairement , soit appuyée pour activer le verrouillage Fn.
Les touches sont rétroéclairées avec trois niveaux de réglage, gérés par
le clavier lui-même avec la touche <kbd>F7</kbd>.</p>
<p>Le pavé tactile du Type Cover est un pavé tactile Windows Precision
connecté via USB HID. Il a un clic décent, mais lorsque la couverture
est inclinée au lieu d&rsquo;être plate sur une surface, cela sonne un peu
creux et bon marché.</p>
<figure>
    <a href="/images/jcs.org/2018-08-31-surface_go_pen-335x251.jpg" title="&#39;Hello from OpenSBD&#39; depuis la Surface Go de Microsoft">
    <picture>
        
        <source srcset="/images/jcs.org/2018-08-31-surface_go_pen-335x251_hu_81f3f0896403a132.webp" type="image/webp">
        
        <img alt="&#39;Hello from OpenSBD&#39; depuis la Surface Go de Microsoft" height="187" loading="lazy" src="/images/jcs.org/2018-08-31-surface_go_pen-335x251_hu_599384dca50febfd.jpg" type="image/jpeg" width="250">
    </picture>
    </a>
    <figcaption>'Hello from OpenSBD' depuis la Surface Go de Microsoft</figcaption>
</figure>
<p>L&rsquo;écran tactile est alimenté par une puce Elantech connectée via
HID-over-i2c, qui prend également en charge la saisie au stylet.
Un stylet Surface Pen est disponible séparément auprès de Microsoft et
est disponible dans les mêmes couleurs que les dalles amovibles &ldquo;Type Covers&rdquo;.
Le stylet fonctionne sans aucun appairage, bien que le bouton supérieur
fonctionne en Bluetooth, il faut donc l&rsquo;appairer pour l&rsquo;utiliser.
Dans tous les cas, le stylet nécessite une pile AAAA pour fonctionner.
Le stylet peut être fixé magnétiquement sur le côté gauche de l&rsquo;écran
lorsqu&rsquo;il n&rsquo;est pas utilisé.</p>
<p>Une béquille peut basculer derrière l&rsquo;écran pour utiliser la tablette
dans un format de portable pouvant s&rsquo;ajuster à n&rsquo;importe quel angle
jusqu&rsquo;à environ 170 degrés. La béquille reste fermement en place partout
où elle est positionnée, ce qui signifie également qu’elle nécessite un
peu de force pour la sortir lors de la première mise en place de la
Surface Go sur un bureau.</p>
<p>En haut de l&rsquo;écran, vous trouverez un bouton d&rsquo;alimentation et des
boutons à bascule pour le volume du son.  Sur le côté droit se trouvent
la prise casque 3,5 mm, le port USB-C, le port d&rsquo;alimentation et le
logement pour carte microSD située derrière la béquille.</p>
<p>La charge peut être effectuée via le port USB-C ou le port de charge
dédié, qui accueille une fixation magnétique similaire à l’adaptateur
MagSafe de première génération d’Apple. Le câble de charge a une LED
blanche qui brille quand il est connecté, ce qui est assez ennuyeux car
il est près de la ligne médiane de l&rsquo;écran plutôt que vers le bas du
clavier. Contrairement au MagSafe d&rsquo;Apple, le voyant n&rsquo;indique pas si la
batterie est chargée ou non. La prise du chargeur électrique peut être
placée vers le haut ou le bas, mais dans les deux sens, je trouve que le
câble d&rsquo;alimentation qui en sort est soumis à une contrainte gênante en
raison de la position verticale du port.</p>
<p>La connectivité sans fil est assurée par une puce Qualcomm Atheros
QCA6174 802.11ac qui fournit également une connectivité Bluetooth.</p>
<p>La plupart des capteurs de l&rsquo;appareil, tels que le gyroscope et le
capteur de lumière ambiante, sont connectés derrière un périphérique PCI
Intel Sensor Hub, ce qui permet de réaliser des économies d&rsquo;énergie car
le processeur hôte n&rsquo;a pas à interroger les capteurs en permanence.</p>
<h2 id="firmware">Firmware</h2>
<p>Pour accéder au menu BIOS ou micrologiciel de la Surface Go, maintenez
le bouton Volume Haut enfoncé, puis appuyez sur le bouton Marche / Arrêt
et relâchez-le, puis relâchez la touche Volume Up lorsque le menu apparaît.
Secure Boot ainsi que divers composants matériels peuvent être désactivés
dans ce menu. L&rsquo;ordre de démarrage peut également être ajusté. Un menu
de démarrage temporaire peut être affiché de la même manière, mais en
utilisant plutôt Volume Down.</p>
<h2 id="installer-openbsd">Installer OpenBSD</h2>
<p>L&rsquo;installation était très facile, le clavier &ldquo;Type Cover&rdquo; fonctionnant
immédiatement, la plupart du matériel étant des composants PC standard.</p>
<p>Pour démarrer l&rsquo;installateur d&rsquo;OpenBSD, utilisez <code>dd</code> pour installer
l&rsquo;image <code>install64.fs</code> sur un disque USB ; entrez dans le BIOS comme
indiqué ci-dessus et désactivez &ldquo;Secure Boot&rdquo;, puis définissez le
périphérique USB comme priorité de démarrage.</p>
<p>Lorsque vous partitionnez le SSD de 128 Go, vous pouvez supprimer en
toute sécurité la partition Windows Recovery qui occupe 1 Go, car elle
ne peut pas réparer une partition Windows totalement supprimée et une
image de récupération complète peut être téléchargée du site Web
Microsoft et copiée sur un disque USB.</p>
<p>Après avoir installé OpenBSD mais avant de redémarrer, montez la
partition EFI ( <code>sd0i</code> ) et supprimez le répertoire <code>/EFI/Microsoft</code>.
Sans cela, la tablette peut essayer de démarrer le chargeur de
récupération Windows. Le chargeur de démarrage EFI d&rsquo;OpenBSD
<code>/EFI/Boot/BOOTX64.EFI</code> sera chargé par défaut.</p>
<p>Un inconvénient à noter : si vous appuyez sur le pavé tactile ou si vous
appuyez sur les touches <kbd>F1</kbd> à <kbd>F6</kbd> lors de
l&rsquo;installation, le &ldquo;Type Cover&rdquo; détachera tous ses périphériques USB,
puis les ré-activera.  Cela est dû au fait que le ramdisk ne contient
aucun pilote de pavé tactile ou autre périphérique prenant en charge les
contrôles de consommation USB HID pour les touches F1-F6. Par conséquent,
les canaux USB de ces périphériques ne sont pas fonctionnels. Il est
probable que le &ldquo;Type Cover&rdquo; se redémarre dans cette situation en tant
que sécurité intégrée pour le forcer à se rattacher, plutôt que de
demander à l&rsquo;utilisateur de détacher le capot et de le rattacher.</p>
<p>Cela ne se produira pas pour le pavé tactile une fois que le noyau
normal sera démarré car il contient le pilote <code>umt</code>. Lisez mes remarques
ci-dessous pour utiliser <code>usbhidcontrol</code> afin de répondre aux touches
F1-F6 qui maintiendront le bon canal USB ouvert afin d&rsquo;empêcher le
détachement ou la réinstallation lors de l&rsquo;utilisation de ces touches.</p>
<h2 id="journal-de-support-openbsd">Journal de support OpenBSD</h2>
<p><strong>23-08-2018</strong> : J&rsquo;ai reçu la Surface Go et j&rsquo;ai démarré un disque USB
OpenBSD après avoir désactivé Secure Boot. J&rsquo;ai pu installer OpenBSD à
la place de la partition Windows, en conservant la partition de
récupération Windows. Après le redémarrage, la Surface a continué
d&rsquo;essayer de démarrer Windows Recovery, qui échouait encore et encore.
J&rsquo;ai démarré sur une installation USB Windows et j&rsquo;ai pu utiliser
<a href="https://www.easyuefi.com/" rel="external">EasyUEFI</a> pour ajouter une nouvelle option
de démarrage UEFI et démarrer explicitement le <code>BOOTX64.EFI</code> d&rsquo;OpenBSD.
OpenBSD démarre maintenant par défaut.</p>
<p>J&rsquo;ai remarqué que l&rsquo;écran avait un pixel mort dans le coin inférieur
gauche, alors j&rsquo;ai décidé de l&rsquo;apporter au Microsoft Store proche pour
un échange. Mais avant, je devais réinstaller Windows, ce qui a pris
plusieurs heures, car la partition de récupération Windows ne peut
actuellement rien récupérer si la partition Windows a été effacée. J&rsquo;ai
téléchargé une image de récupération de la Surface à partir du site Web
de Microsoft et créer un disque USB pour réinstaller Windows. Finalement,
je me suis rendu au Microsoft Store et ils m&rsquo;ont rapidement donné une
nouvelle en échange.</p>
<p>Lors de l&rsquo;installation d&rsquo;OpenBSD sur le nouveau périphérique, j&rsquo;ai
décidé d&rsquo;effacer la partition de récupération de Windows car elle est de
toute façon inutile et me permettrait d&rsquo;économiser un gigaoctet d&rsquo;espace
supplémentaire. Avant de redémarrer, j&rsquo;ai compris que les variables de
démarrage UEFI pointaient d&rsquo;abord vers les fichiers EFI de récupération
de Windows dans <code>\EFI\Microsoft</code>. J&rsquo;ai donc supprimé tout ce répertoire
en laissant <code>\EFI\Boot\BOOTX64.EFI</code> qui est le chargeur de démarrage
d&rsquo;OpenBSD. Cela a fonctionné comme prévu et OpenBSD démarre maintenant
par défaut.</p>
<p><strong>24-08-2018</strong> : Le pavé tactile du Type Cover se connecte à <code>ums</code> mais
c&rsquo;est un pavé tactile Windows Precision qui devrait donc fonctionner
comme mon pilote <code>imt</code> , mais via USB. <code>ums</code> ne prend en charge qu&rsquo;un
seul doigt de saisie et le matériel a la fonction &ldquo;tap-to-click&rdquo; activée
par défaut, il ne peut pas être désactivé. J&rsquo;ai écrit un nouveau pilote
<a href="https://github.com/jcs/openbsd-src/commit/552927b7d737c9c58071e75c7eb396ef59b79594" rel="external"><code>umt</code></a>
pour le brancher sur USB à la place de <code>hidmt</code>, ensuite j&rsquo;ai perdu
beaucoup de temps pour déboguer les raisons pour lesquelles le
périphérique ne fonctionnait pas correctement dans le mode PTP. Je l&rsquo;ai
traqué jusqu&rsquo;à trouver une certaine confusion entre <code>ihidev</code> et <code>hidmt</code>
qui devait être corrigés en premier, j&rsquo;ai donc envoyé un diff à <code>tech@</code>.</p>
<p><strong>25-08-2018</strong> : J&rsquo;ai <a href="https://github.com/openbsd/src/commit/253b28d04b9c6635c4d2e127060005b0bf7c3471" rel="external">envoyé</a>
les modifications des pilotes <code>ihidev</code> et <code>hidmt</code> et un
<a href="https://marc.info/?l=openbsd-tech&amp;m=153522257408102&amp;w=2" rel="external">diff pour importer <code>umt</code></a>
à <code>tech@</code> pour analyse. Il a été rapidement
<a href="https://github.com/openbsd/src/commit/737d705b8780db06a36e2cfc49360998fb7264ee" rel="external">importé</a> .</p>
<p><strong>28-08-2018</strong> : Ces deux derniers jours, j&rsquo;ai passé du temps à chercher
ce qui était nécessaire pour que l&rsquo;écran tactile Elan fonctionne. Il
s&rsquo;attache à <code>ihidev</code> en tant que périphérique HID-over-i2c, mais il ne
s&rsquo;attache pas à <code>imt</code>. Finalement, j&rsquo;ai découvert que ce n&rsquo;est pas un
périphérique compatible PTP, mais conforme à l&rsquo;ancien multitouch de type
Windows 8. J&rsquo;ai <a href="https://github.com/jcs/openbsd-src/commit/a6499db211d988462561564cd3284b11501e42ac" rel="external">commencé à ajouter</a>
un support pour ces périphériques de type Windows 8 à <code>hidmt</code> et déplacé
du code dupliqué dans <code>umt</code> et <code>imt</code> dans <code>hidmt</code>.</p>
<p>J&rsquo;ai aussi examiné les boutons de volume en haut de l&rsquo;écran.
Malheureusement, ils ne fonctionnent pas avec notre pilote
<a href="https://man.openbsd.org/acpisurface.4" rel="external"><code>acpisurface</code></a> existant, alors
j&rsquo;ai démarré un disque USB Linux et ai tracé leur fonctionnement.
Apparemment, c&rsquo;est un périphérique &ldquo;Intel 5-button Array&rdquo; qui fonctionne
via ACPI. J&rsquo;ai écrit un nouveau pilote
<a href="https://github.com/jcs/openbsd-src/commit/0befab1a6ae8708140d418d5affeb0a76d84ce4b" rel="external"><code>acpihid</code></a>
pour cela et les boutons de volume contrôlent maintenant le volume audio.
Il y a certaines surcharges dans <code>acpihid</code>, dans la gestion du bouton
d&rsquo;alimentation et de la méthode d&rsquo;interruption ACPI GPE standard, afin
de recevoir la pression sur le bouton d&rsquo;alimentation. J&rsquo;ai donc dû prendre
en compte  que <code>acpibtn</code> capture <code>acpihid</code> s&rsquo;il est attaché. Ce serait
bien s&rsquo;il y avait une variable <code>sysctl</code> comme <code>machdep.lidaction</code> qui
spécifiait si le bouton d&rsquo;alimentation était en mode arrêt, suspendu ou
ne faisait rien.</p>
<p><strong>29-08-2018</strong> : Je voulais faire fonctionner les fonctions <kbd>F1</kbd>
à <kbd>F6</kbd> du clavier (luminosité, lecture / pause, sourdine,
diminution / augmentation du volume) sur le Type Cover. Actuellement,
chaque fois qu&rsquo;ils sont pressés, le Type Cover redémarre, car le
rétro-éclairage s&rsquo;éteint et tous ses périphériques USB se détachent puis
se reconnectent. En traçant comment cela fonctionne sous Linux, j&rsquo;ai vu
qu&rsquo;il s&rsquo;agissait essentiellement d&rsquo;utiliser leur pilote générique
<code>hid-input</code>, donc il ne devrait pas avoir besoin de le personnaliser.
J&rsquo;ai commencé à travailler sur un pilote générique d&rsquo;entrée USB HID
(contrairement à <code>ukbd</code> / <code>hidkbd</code> qui nécessite des utilisations
spécifiques au clavier), mais j&rsquo;ai eu des soucis sur
<a href="https://man.openbsd.org/usbhidaction" rel="external"><code>usbhidaction</code></a> que nous avons
déjà en base et qui devrait bien fonctionner pour cette tâche.</p>
<p>Malheureusement, <code>usbhidaction</code> requiert de connaître le chemin
spécifique uhid du périphérique HID qui doit être contrôlé et le quitter
dès que le périphérique disparaît. Pour la dalle Type Cover de la Surface,
ce périphérique peut changer en fonction de ce qui a été branché au
démarrage, et se détachera à chaque fois que la machine sera arrêtée
alors <code>usbhidaction</code> s&rsquo;arrêtera simplement.</p>
<p>Après avoir passé beaucoup de temps à modifier <code>usbhidaction</code> pour
interroger le périphérique <code>/dev/usbN</code> afin d&rsquo;attendre les ajouts et les
suppressions de périphérique, j&rsquo;ai réalisé que la page de manuel était
obsolète et que tous ces événements étaient sortis du noyau il y a
plusieurs années. J&rsquo;ai
<a href="https://github.com/openbsd/src/commit/a544fd91425c575826734076091eb434c3582ef6" rel="external">enlevé</a>
cette ligne dans la page de manuel.</p>
<p><strong>30-08-2018</strong> : Afin d&rsquo;être capable d&rsquo;utiliser <code>usbhidaction</code> pour
qu&rsquo;il trouve automatiquement un périphérique USB en fonction de son
fournisseur et de son identifiant, et être capable d&rsquo;attendre que le
périphérique s&rsquo;affiche automatiquement, je l&rsquo;ai connecté à
<a href="https://man.openbsd.org/hotplug" rel="external"><code>/dev/hotplug</code></a>. Malheureusement,
hotplug ne prend en charge qu&rsquo;un seul lecteur simultané. J&rsquo;ai donc
<a href="https://github.com/jcs/openbsd-src/commit/1d49b6870e7d96ebdb72bc79b676479f47cfaaee" rel="external">implémenté le clonage de périphérique</a>
dans le pilote <code>hotplug</code> afin que plusieurs processus puissent lire à
partir de <code>/dev/hotplug</code> et que chacun reçoive sa propre file d&rsquo;événements.
Je l&rsquo;ai envoyé par courrier électronique à la liste des développeurs
OpenBSD et j&rsquo;ai reçu quelques premiers commentaires à ce sujet.</p>
<p>J&rsquo;ai fait beaucoup de progrès sur les changements d’ <code>usbhidaction</code>, et
je <a href="https://github.com/jcs/openbsd-src/commit/bdd58222f11ff91a0576bd7506306b740307d38d" rel="external">les ai envoyés</a>
dans mon arborescence.</p>
<p>J&rsquo;ai également <a href="https://github.com/openbsd/src/commit/a79e753a0f4aa24616d8aacea73b5502a256f5f5" rel="external">envoyé</a>
un changement en amont pour créer 8 périphériques <code>/dev/uhidN</code>,
puisqu&rsquo;il n&rsquo;y en avait que 4 auparavant.</p>
<p><strong>31-08-2018</strong> : J&rsquo;ai décidé d&rsquo;abandonner mon support multitouch Windows
8 pour le moment, car l&rsquo;écran tactile devrait être utilisable avec le
support de base par <code>ims</code> (agissant comme une souris à un bouton).
Utiliser <code>imt</code> signifiait de réclamer tous les rapports HID (25 !) sur
le périphérique, ce qui brisait la prise en charge de l&rsquo;utilisation d&rsquo;un
stylet et mon stylet Surface est arrivé, je voulais l&rsquo;utiliser. De cette
façon, <code>ims</code> peut juste l&rsquo;attacher au rapport de l&rsquo;écran tactile et un
autre <code>ims</code> peut l&rsquo;attacher au rapport de saisie du stylet.</p>
<p>En faisant des <code>ims</code> correspondant aux rapports de l&rsquo;écran tactile, je
suis tombé sur ce qui ressemble à un bogue dans notre analyseur HID (ou,
il n&rsquo;est tout simplement pas pris en charge) où il correspondait à
l&rsquo;utilisation de pages qu&rsquo;il ne devrait pas. Le résultat de ceci était
que, quand <code>hidms</code> cherchait la page d&rsquo;utilisation indiquant le minimum
logique et le maximum X / Y de l&rsquo;écran (afin de pouvoir mapper les
coordonnées d&rsquo;entrée de l&rsquo;écran tactile sur l&rsquo;affichage de l&rsquo;écran), il
y avait des utilisations pour d&rsquo;autres choses sans rapport, cela faisait
penser au pilote que l’écran était beaucoup plus grand qu’il ne l’était.
Lorsque je touchais l&rsquo;écran et que je le parcourais complètement, cela
ne faisait déplacer le curseur que d&rsquo;un quart environ.</p>
<p>J&rsquo;ai <a href="https://marc.info/?l=openbsd-tech&amp;m=153575195129139&amp;w=2" rel="external">envoyé un diff</a>
à <code>tech@</code> pour contourner cet ims et attacher des <code>ims</code> aux écrans tactiles.</p>
<p><strong>01-09-2018</strong> : Les diff d&rsquo;<a href="https://github.com/openbsd/src/commit/cecb02cd4eb9c092e59ac7b37bad207101e1a50f" rel="external"><code>hidms</code></a>
et d&rsquo;<a href="https://github.com/openbsd/src/commit/f320308cc2368ecbbecc04b9caf0f74523c62ab0" rel="external"><code>ims</code></a>
ont été acceptés. OpenBSD 6.4 prendra en charge l’écran tactile, le
stylet, le clavier et le pavé tactile multitouch.</p>
<p>Je suis toujours en attente de retours sur mon changement de <code>hotplug</code>,
ce qui me permettra ensuite de développer plus profondément mes
modifications sur <code>usbhidaction</code>.</p>
<p>J&rsquo;ai aussi besoin de commencer à travailler sur un pilote pour le
périphérique PCI Intel Sensor Hub qui me permettrait ensuite de prendre
en charge le capteur de lumière ambiante et le gyroscope pour la
détection de la rotation. Cependant, en regardant le pilote Linux, il
semble qu&rsquo;il y ait une tonne de code et bien sûr, il n’y a pas de
documentation ouverte pour que je puisse trouver.</p>
<h2 id="résumé-du-support-actuel-dopenbsd">Résumé du support actuel d&rsquo;OpenBSD</h2>
<p>Le statut est relatif à OpenBSD-current en date du 03-09- 2018.</p>
<table>
  <thead>
      <tr>
          <th>Composant</th>
          <th>Fonctionnel</th>
          <th>Remarques</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Adaptateur électrique AC</td>
          <td>Oui</td>
          <td>Pris en charge via <a href="https://man.openbsd.org/acpiac.4" rel="external"><code>acpiac</code></a> et le statut est disponible via <code>apm</code> et <code>hw.sensors</code> , qui supporte également la charge via USB-C.</td>
      </tr>
      <tr>
          <td>Détecteur de lumière ambiante</td>
          <td>Non</td>
          <td>Connecté derrière un périphérique PCI Intel Sensor Hub qui nécessite un nouveau pilote.</td>
      </tr>
      <tr>
          <td>Audio</td>
          <td>Oui</td>
          <td>Audio HDA ​​avec un codec Realtek 298 pris en charge par <a href="https://man.openbsd.org/azalia.4" rel="external"><code>azalia</code></a>.</td>
      </tr>
      <tr>
          <td>État de la batterie</td>
          <td>Oui</td>
          <td>Pris en charge via <a href="https://man.openbsd.org/acpibat.4" rel="external"><code>acpibat</code></a> et le status est disponible via <code>apm</code> et <code>hw.sensors</code>.</td>
      </tr>
      <tr>
          <td>Bluetooth</td>
          <td>Non</td>
          <td>Le périphérique Atheros apparaît comme un périphérique <a href="https://man.openbsd.org/ugen.4" rel="external"><code>ugen</code></a> , mais OpenBSD ne prend pas en charge le Bluetooth. Peut être désactivé dans le BIOS.</td>
      </tr>
      <tr>
          <td>Les caméras</td>
          <td>Non</td>
          <td>Il existe apparemment des caméras avant, arrière et infrarouge, dont aucune n&rsquo;est prise en charge (ni souhaité). Peut être désactivées dans le BIOS.</td>
      </tr>
      <tr>
          <td>Le Gyroscope</td>
          <td>Non</td>
          <td>Connecté derrière le périphérique PCI Intel Sensor Hub qui requiert un nouveau pilote qui pourrait alimenter le [[https://man.openbsd.org/man9/sensor_attach.9</td>
      </tr>
      <tr>
          <td>Hibernation</td>
          <td>Oui</td>
          <td>Fonctionne bien avec <code>zzz</code></td>
      </tr>
      <tr>
          <td>Slot MicroSD</td>
          <td>Oui</td>
          <td>Un Realtek RTS522A, supporté par <a href="https://man.openbsd.org/rtsx.4" rel="external"><code>rtsx</code></a>.</td>
      </tr>
      <tr>
          <td>Le SSD</td>
          <td>Oui</td>
          <td>Le périphérique Toshiba NVMe accessible via <a href="https://man.openbsd.org/nvme.4" rel="external"><code>nvme</code></a>.</td>
      </tr>
      <tr>
          <td>Le stylet</td>
          <td>Oui</td>
          <td>Fonctionne sur l&rsquo;écran tactile via <a href="https://man.openbsd.org/ims.4" rel="external"><code>ims</code></a>. Le bouton situé en haut du stylet nécessite la prise en charge du Bluetooth qui n&rsquo;est pas pris en charge. Du fait que dwiic nécessite toujours l&rsquo;interrogation de ces chipsets, dessiner avec le stylet n&rsquo;est pas aussi fluide qu&rsquo;avec des interruptions correctes.</td>
      </tr>
      <tr>
          <td>Mise en veille / Réveil</td>
          <td>Oui</td>
          <td>Fonctionne bien à partir de <code>zzz</code> et en fermant le Type Cover contre l&rsquo;écran. Il ne se réveille pas automatiquement lorsque vous retirez le Type Cover, il faut appuyer sur le bouton d&rsquo;alimentation pour le réveiller.</td>
      </tr>
      <tr>
          <td>L&rsquo;Écran tactile</td>
          <td>Oui</td>
          <td>HID-over-I2C, supporté par <a href="https://man.openbsd.org/ims.4" rel="external"><code>ims</code></a>.</td>
      </tr>
      <tr>
          <td>Le clavier Type Cover</td>
          <td>Oui</td>
          <td>USB, supporté par <a href="https://man.openbsd.org/ukbd.4" rel="external"><code>ukbd</code></a>. 3 niveaux de contrôle du rétroéclairage sont réglables par le clavier lui-même avec <kbd>F7</kbd>. Les actions des touches <kbd>F1</kbd> à <kbd>F6</kbd> apparaissent dans le rapport 3 et peuvent être répondues avec <code>usbhidaction -u 045e:096f -r 3</code>.</td>
      </tr>
      <tr>
          <td>Le pavé tactile Type Cover</td>
          <td>Oui</td>
          <td>USB, pris en charge par mon nouveau pilote <a href="https://man.openbsd.org/umt.4" rel="external"><code>umt</code></a> pour le multitouch à 5 doigts, le défilement à deux doigts, l&rsquo;hystérésis et être capable de désactiver le tap-to-click qui est activé par défaut en mode souris normal.</td>
      </tr>
      <tr>
          <td>USB</td>
          <td>Oui</td>
          <td>Le port USB-C fonctionne bien pour les données et la charge.</td>
      </tr>
      <tr>
          <td>La Vidéo</td>
          <td>Oui</td>
          <td><a href="https://man.openbsd.org/inteldrm.4" rel="external"><code>inteldrm</code></a> a pris en charge Kaby Lake en ajoutant la vidéo accélérée, le DPMS, le contrôle gamma, le contrôle de rétroéclairage intégré et la reprise S3 appropriée.</td>
      </tr>
      <tr>
          <td>Les boutons de volume</td>
          <td>Oui</td>
          <td>Intel à 5 ​​boutons, pris en charge par mon nouveau pilote <a href="https://github.com/jcs/openbsd-src/commit/0befab1a6ae8708140d418d5affeb0a76d84ce4b" rel="external"><code>acpihid</code></a> non encore importé en amont.</td>
      </tr>
      <tr>
          <td>Wifi</td>
          <td>Non</td>
          <td>Puce sans fil Qualcomm Atheros QCA6174 802.11ac, non prise en charge. FreeBSD a un <a href="https://github.com/erikarn/athp" rel="external">port en cours de  travail d’<code>ath10k</code></a> partir de Linux (sous licence ISC) qui peut être porté. J&rsquo;utilise actuellement un petit adaptateur sans fil USB-A qui est rendu moins volumineux par un adaptateur USB-A vers USB-C.</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Joshua Stein !</p>
<p><em>Cette page est la traduction de la page
<strong>[OpenBSD on Microsoft Surface Go]]]<a href="https://jcs.org/2018/08/31/surface_go" rel="external">1</a></strong> du site <strong>BSDHowto.ch</strong>.</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;OpenBSD on the Microsoft Surface Go&#39; de l&#39;auteur Joshua Stein]]></summary>
        <published>2018-09-01T16:25:22+02:00</published>
        <updated>2023-07-25T18:11:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:32cd1efb-74fb-0964-1af8-cb7603a25feb</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/fausses-croyances-dev-temps-2/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: D&#39;autres fausses croyances des développeurs à-propos du temps</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Dev" scheme="http://doc.huc.fr.eu.org/fr/tags/dev/" />
        <category term="Temps" scheme="http://doc.huc.fr.eu.org/fr/tags/temps/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="http://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time" rel="external">More Falsehoods programmers believe about time</a></strong>&rdquo;,
écrit par l&rsquo;auteur Noah Sussman, sous Licence CC-By.</p>
<hr>
<h1 id="dautres-fausses-croyances-des-développeurs-à-propos-du-temps">D&rsquo;autres fausses croyances des développeurs à-propos du temps</h1>
<p>(…)</p>
<p>Toutes ces hypothèses sont fausses :</p>
<ol>
<li>Les décalages entre deux fuseaux horaires resteront constants.</li>
<li>OK, hormis les bizarreries historiques, les décalages entre deux
fuseaux horaires ne changeront pas dans le futur.</li>
<li>Les changements dans les décalages entre deux fuseaux horaires se
produiront avec un préavis suffisant.</li>
<li>L&rsquo;heure d&rsquo;été a lieu au même moment chaque année.</li>
<li>L&rsquo;heure d&rsquo;été a lieu au même moment dans chaque fuseau horaire</li>
<li>L&rsquo;heure d&rsquo;été s&rsquo;ajuste toujours d&rsquo;une heure</li>
<li>Les mois ont soit 28, 29, 30, ou 31 jours.</li>
<li>Le jour du mois avance toujours de manière contiguë de N vers N+1 ou
1, sans discontinuer.</li>
<li>Un seul calendrier système est utilisé à la fois.</li>
<li><a href="https://support.microsoft.com/en-us/help/214326/excel-incorrectly-assumes-that-the-year-1900-is-a-leap-year" rel="external">Il y a une année bissextile chaque année divisible par 4</a>.</li>
<li>Les années non bissextiles ne contiendront jamais de jour bissextile.</li>
<li>Il sera toujours facile de calculer la durée d&rsquo;un nombre d&rsquo;heures et
de minutes à partir d&rsquo;un point particulier du temps.</li>
<li>Le même mois a le même nombre de jours, partout !</li>
<li>Le temps Unix est complètement ignorant de tout excepté des secondes.</li>
<li>Le temps Unix est le nombre de secondes depuis le 1er Janvier 1970.</li>
<li>Le jour précédent Samedi est toujours Vendredi.</li>
<li>Les fuseaux horaires contiguës ne sont pas distant de plus d&rsquo;une
heure (ainsi nous n&rsquo;avons pas besoin de tester ce qui arrive à
l&rsquo;avionique lors d&rsquo;un survol de la Ligne de Date Internationale)</li>
<li>Deux fuseaux horaires qui différent seront différents d&rsquo;un nombre
entier de demi-heures.</li>
<li>OK, de quart d&rsquo;heures.</li>
<li>OK, de secondes, mais ce sera une différence constante si nous
ignorons l&rsquo;heure d&rsquo;été.</li>
<li>Si vous créez deux objets de date l&rsquo;un à côté de l&rsquo;autre, ils
représenteront le même temps (un fantastique générateur d&rsquo;Heisenbug).</li>
<li>Vous pouvez vous attendre à ce que l&rsquo;horloge atteigne exactement
HH:MM:SS en échantillonnant une fois par seconde.</li>
<li>Si un processus s&rsquo;exécute pendant n secondes et puis se termine, il
se sera passé approximativement n seconds par l&rsquo;horloge système à la
fin de l&rsquo;exécution.</li>
<li>Les semaines commencent un Lundi.</li>
<li>Les jours commencent le matin.</li>
<li>Les jours fériés contiennent un nombre entier de jours.</li>
<li>Les fins de semaine consistent en Samedi et Dimanche.</li>
<li>Il est possible d&rsquo;établir un ordre complet d&rsquo;horodatage qui est
utile en-dehors de votre système.</li>
<li>Le décalage de l&rsquo;heure locale (depuis UTC) ne changera pas durant
les heures de bureau.</li>
<li>Thread.sleep(1000) dort durant 1000 millisecondes</li>
<li>Thread.sleep(1000) dort durant un temps ≥ 1000 millisecondes.</li>
<li>Il y a 60 secondes dans chaque minute</li>
<li>Les horodatages <a href="https://www.metafilter.com/117073/Falsehoods-Programmers-Believe#4405410" rel="external">avancent toujours de manière monotone</a>.</li>
<li>GMT et UTC sont les mêmes fuseaux horaires.</li>
<li>La Grande-Bretagne utilise GMT.</li>
<li>Le temps va toujours de l&rsquo;avant.</li>
<li>La différence entre le temps actuel et une semaine par rapport à
l&rsquo;heure actuelle est toujours de 7 * 86400 secondes.</li>
<li>La différence entre deux horodatages est une mesure précise du temps
écoulée entre les deux.</li>
<li>24:12:34 est une heure invalide.</li>
<li>Chaque nombre entier est une année théorique possible.</li>
<li>Si vous affichez une date, l&rsquo;heure affichée a la même seconde que
l&rsquo;heure stockée.</li>
<li>Ou la même année.</li>
<li>Mais au moins la différence numérique entre l&rsquo;année affichée et
celle enregistrée sera au minimum de 2.</li>
<li>Si vous avez une date dans le format correct YYYY-MM-DD, l&rsquo;année est
constituée de quatre caractères.</li>
<li>Si vous fusionnez deux dates, en prenant le mois de la première et
le jour ou l&rsquo;année de la seconde, vous aurez une date valide.</li>
<li>Mais cela fonctionnera, si les deux années sont des années bissextiles.</li>
<li>Si vous prenez un algorithme publié par le W3C pour le calcul de
durées de dates, cela fonctionnera dans tous les cas.</li>
<li>La bibliothèque standard supporte les années négatives et les années
au-delà de 10000.</li>
<li>Les fuseaux horaires différent toujours d&rsquo;une heure pleine.</li>
<li>Si vous convertissez un horodatage avec une précision de la
milliseconde vers une date et une heure avec la précision de la
seconde, vous pouvez ignorez les millisecondes.</li>
<li>Mais vous pouvez ignorez les millisecondes, s&rsquo;il y en a moins que 0.5</li>
<li>Les années à deux chiffres doivent être situées entre 1900 et 2099</li>
<li>Si vous analysez une date et une heure, vous pouvez lire les nombres
caractère par caractère, sans avoir besoin de revenir en arrière.</li>
<li>Mais si vous imprimez une date et une heure, vous pouvez écrire les
nombres caractère par caractère, sans avoir besoin de revenir en
arrière.</li>
<li>Vous n&rsquo;aurez jamais besoin d&rsquo;analyser un format tel que <strong>&mdash;12Z</strong>
ou <strong>P12Y34M56DT78H90M12.345S</strong></li>
<li>Il y a seulement 24 fuseaux horaires.</li>
<li>Les fuseaux horaires sont toujours a des heures complètes depuis UTC.</li>
<li>L&rsquo;heure d&rsquo;été (DST) commence et termine à la même date partout.</li>
<li>L&rsquo;heure d&rsquo;été est toujours avancée d&rsquo;une heure.</li>
<li>Lire l&rsquo;horloge d&rsquo;un client et la comparer avec UTC est une bonne
manière de déterminer leur fuseau horaire.</li>
<li>La pile logicielle essaiera ou n&rsquo;essaiera pas automatiquement
d&rsquo;ajuster le fuseau horaire ou l&rsquo;heure d&rsquo;été.</li>
<li>Mon logiciel est seulement utilisé en interne ou localement, aussi
je n&rsquo;ai pas besoin de me soucier des fuseaux horaires.</li>
<li>Ma pile logicielle la gérera sans que j&rsquo;ai quoique ce soit de
spécial à faire.</li>
<li>Je peux facilement maintenir par moi-même une liste de fuseau horaire.</li>
<li>Toutes les mesures de temps d&rsquo;une horloge donnée se feront dans le
même <a href="https://www.reddit.com/r/programming/comments/v8s0y/falsehoods_programmers_believe_about_time/c52kqpa/" rel="external">cadre de référence</a>.</li>
<li>Les années ont 365 ou 366 jours.</li>
<li>Chaque date calendaire est suivie de la suivante dans l&rsquo;ordre, sans
saut.</li>
<li>Une date ou une heure donnée sans ambiguïté identifie un moment unique.</li>
<li>Les années bissextiles arrivent tous les 4 ans.</li>
<li>Vous pouvez déterminer le fuseau horaire depuis l&rsquo;état ou la province.</li>
<li>Vous pouvez déterminer le fuseau horaire depuis la cité ou la ville.</li>
<li>Le temps passe à la même vitesse du haut d&rsquo;une montagne et en bas
d&rsquo;une vallée.</li>
<li>Une heure est aussi longue que la suivante dans tous les systèmes de
temps.</li>
<li>Vous pouvez calculer quand les secondes intercalaires seront ajoutées.</li>
<li>La précision d&rsquo;un type de donnée retournée par une fonction
getCurrentTime() est la même que la précision de la fonction.</li>
<li>Deux appels subséquents à la fonction getCurrentTime() retourneront
des résultats distincts.</li>
<li>Le second de deux appels subséquents à la fonction getCurrentTime()
aura un résultat plus grand.</li>
<li>Le logiciel ne fonctionnera jamais sur un vaisseau spatial en orbite
d&rsquo;un trou noir.</li>
</ol>
<hr>
<p><strong>Sérieusement ? Des trous noirs ?</strong></p>
<p>Hé, si
<a href="https://www.wired.com/2012/06/falsehoods-programmers-believe-about-time/" rel="external">Bruce Sterling dit que mon logiciel a besoin d&rsquo;être résilient contre les distorsions du temps causé par les trous noirs</a>,
je vais être attentif à ce propos.</p>
<hr>
<p><em>Le reste n&rsquo;est volontairement pas traduit du fait de remerciements de
l&rsquo;auteur envers plusieurs personnes…</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;More Falsehoods programmers believe about time&#39; de l&#39;auteur Noah Sussman, sous Licence CC-By]]></summary>
        <published>2018-06-19T13:26:06+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c53daef9-8546-b37c-7900-ad181e878ff8</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/fausses-croyances-dev-temps/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Fausses croyances des développeurs à-propos du temps</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Dev" scheme="http://doc.huc.fr.eu.org/fr/tags/dev/" />
        <category term="Temps" scheme="http://doc.huc.fr.eu.org/fr/tags/temps/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time" rel="external">Falsehoods programmers believe about time</a></strong>&rdquo;,
écrit par l&rsquo;auteur Noah Sussman, sous Licence CC-By.</p>
<hr>
<h1 id="fausses-croyances-des-développeurs-à-propos-du-temps">Fausses croyances des développeurs à-propos du temps</h1>
<p>(…)</p>
<p>Toutes ces hypothèses sont fausses :</p>
<ol>
<li>Il y a toujours 24 heures dans une journée.</li>
<li>Les mois ont soit 30 ou 31 jours.</li>
<li>Les années ont 365 jours.</li>
<li>Février a toujours 28 jours.</li>
<li>Une période de 24 heures commencera toujours ou terminera durant le
même jour, (ou la semaine, ou le mois).</li>
<li>Une semaine commence toujours et termine dans le même mois.</li>
<li><a href="https://www.reddit.com/r/programming/comments/v8s0y/falsehoods_programmers_believe_about_time/c52k8m9/" rel="external">Une semaine (ou un mois) commence toujours et termine dans la même année</a>.</li>
<li>La machine sur laquelle le programme fonctionne sera toujours dans le
fuseau horaire GMT.</li>
<li>OK, ce n&rsquo;est pas vrai. Mais au moins le fuseau horaire dans lequel le
programme fonctionne ne changera jamais.</li>
<li>Bien, assurément il n&rsquo;y aura jamais de changement de fuseau horaire
dans lequel un programme s&rsquo;exécute <em>en production</em>.</li>
<li>L&rsquo;horloge système sera toujours paramétrée à une heure locale correcte.</li>
<li>L&rsquo;horloge système sera toujours paramétrée à une heure qui n&rsquo;est pas
très différente de l&rsquo;heure locale correcte.</li>
<li>Si l&rsquo;horloge système est incorrecte, il y aura toujours le même nombre
constant de secondes.</li>
<li>L&rsquo;horloge du serveur et celle du client seront toujours paramétrées
sur la même heure.</li>
<li>L&rsquo;horloge du serveur et celle du client seront toujours paramétrées à
peu près à la même heure.</li>
<li>OK, mais l&rsquo;heure du serveur et celle du client ne seront jamais
différentes au-delà de la maîtrise <em>des décennies</em>.</li>
<li>Si l&rsquo;horloge du serveur et celle du client ne sont pas synchronisées,
elles seront toujours au moins désynchronisées d&rsquo;un nombre constant
de secondes.</li>
<li>L&rsquo;horloge du serveur et celle du client utiliseront le même fuseau
horaire.</li>
<li>L&rsquo;horloge système ne sera jamais paramétrée sur une heure d&rsquo;un passé
distant ou d&rsquo;un lointain future.</li>
<li>Le temps n&rsquo;a pas de commencement et <a href="https://en.wikipedia.org/wiki/Year_2038_problem" rel="external">pas de fin</a>.</li>
<li>Une minute d&rsquo;une horloge système a exactement la même durée qu&rsquo;une
minute sur <a href="https://en.wikipedia.org/wiki/Atomic_clock" rel="external">une autre horloge</a>.</li>
<li>OK, mais la durée d&rsquo;une minute d&rsquo;une horloge système sera la plus
proche de la durée d&rsquo;une minute sur la plupart des autres horloges.</li>
<li>D&rsquo;accord, mais la durée d&rsquo;une minute d&rsquo;une horloge système ne sera
jamais plus grande  que celle d&rsquo;une heure.</li>
<li>Tu n&rsquo;es pas sérieux.</li>
<li>La plus petite unité du temps est la seconde.</li>
<li>OK, une mili-seconde</li>
<li>Il ne sera jamais nécessaire de régler l&rsquo;heure du système sur une
autre valeur que celle de l&rsquo;heure locale correcte.</li>
<li>OK, <em>les tests</em> peuvent nécessiter le paramétrage de l&rsquo;heure du
système sur une autre valeur que celle de l&rsquo;heure locale mais il ne
sera jamais nécessaire de faire cela <em>en production</em>.</li>
<li>L&rsquo;horodatage sera toujours spécifié dans un format communément compris,
tel que 1339972628 ou 133997262837.</li>
<li>L&rsquo;horodatage sera toujours spécifié dans un même format.</li>
<li>L&rsquo;horodatage aura toujours le même niveau de précision.</li>
<li>Un horodatage d&rsquo;une précision suffisante peut être considéré unique en
toute sécurité.</li>
<li>Un horodatage représente l&rsquo;heure à laquelle un événement s&rsquo;est produit.</li>
<li>Les dates humainement compréhensibles peuvent être spécifiées dans un
format universellement compris tel que 05/07/11.</li>
</ol>
<hr>
<p><strong>La réflexion à-propos du fait que la minute puisse être plus longue
qu&rsquo;une heure est une blague, n&rsquo;est-ce pas ?</strong></p>
<p>Non.</p>
<p>C&rsquo;est un fascinant bogue dans de vieilles version de
<a href="https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine" rel="external">KVM</a> sur
CentOS. Spécifiquement, une machine virtuelle KVM ne savait pas qu&rsquo;elle
ne fonctionnait pas sur du matériel physique. Cela signifiait que le
système hôte mettait la VM dans un état de veille, l&rsquo;horloge système
virtualisée conservait le temps qu&rsquo;elle avait <em>au moment de sa suspension</em>.</p>
<p>P. ex. si la VM était suspendue à 13:00 et qu&rsquo;elle était remise à un
état d&rsquo;activité deux heures plus tard (à 15:00), l&rsquo;horloge système sur
la VM reflétait toujours l&rsquo;heure locale à 13:00. Le résultat était que
chaque fois qu&rsquo;une machine virtuelle KVM devenait inactive, l&rsquo;OS hôte la
mettait dans un état suspendu et l&rsquo;horloge système de la machine
virtuelle commençait à s&rsquo;éloigner de la réalité, parfois d&rsquo;une large
marge en fonction de la durée pendant laquelle la machine virtuelle
était restée inactive.</p>
<p>Il y avait une tâche cron qui pouvait être installée pour garder
l&rsquo;horloge système virtualisée en ligne avec l&rsquo;horloge matérielle de l&rsquo;OS
hôte. Mais il était facile d&rsquo;oublier de le faire sur de nouvelles VMs et
l&rsquo;échec à le faire a conduit à beaucoup d&rsquo;hilarité. Le bogue a été
corrigé dans les versions plus récentes.</p>
<hr>
<p><em>Le reste n&rsquo;est volontairement pas traduit du fait de remerciements de
l&rsquo;auteur envers plusieurs personnes…</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;Falsehoods programmers believe about time&#39; de l&#39;auteur Noah Sussman, sous Licence CC-By]]></summary>
        <published>2018-06-19T13:11:11+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:58f055e4-466c-6965-3596-584f43d6686c</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/tumfatig.net/openbsd-collectd-influxdb-grafana/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Monitorer OpenBSD en utilisant CollectD, InfluxDB et Grafana</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Collectd" scheme="http://doc.huc.fr.eu.org/fr/tags/collectd/" />
        <category term="InfluxDB" scheme="http://doc.huc.fr.eu.org/fr/tags/influxdb/" />
        <category term="Grafana" scheme="http://doc.huc.fr.eu.org/fr/tags/grafana/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="https://www.tumfatig.net/2018/monitoring-openbsd-using-collectd-influxdb-and-grafana/" rel="external">Monitoring OpenBSD using CollectD, InfluxDB and Grafana</a></strong>&rdquo;,
écrit par Joel Carnat.</p>
<hr>
<h1 id="monitorer-openbsd-en-utilisant-collectd-influxdb-et-grafana">Monitorer OpenBSD en utilisant CollectD, InfluxDB et Grafana</h1>
<ul>
<li>OS concerné : <strong>6.2-current et &gt;</strong></li>
<li>Logiciels packagés : CollectD, InfluxDB, Grafana</li>
</ul>
<hr>
<p>Regardons comment monitorer OpenBSD en utilisant le collecteur CollectD
et le tableau de bord de rendu Grafana. OpenBSD 6.2-current fournit les
packages InfluxDB et Grafana. Une superbe pile pour obtenir de jolis
graphiques.</p>
<h2 id="hébergement-des-données">Hébergement des données</h2>
<p>Les métriques du système sont stockés dans InfluxDB ; parce qu&rsquo;il peut
être utilisé comme ressource pour Grafana. L&rsquo;installation et la
configuration sont simples. L&rsquo;essentiel est d&rsquo;activer le protocole de
collecte collectd.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add influxdb</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># vi /etc/influxdb/influxdb.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[[</span>collectd<span style="color:#5bc4bf">]]</span>
</span></span><span style="display:flex;"><span>  <span style="color:#ef6155">enabled</span> <span style="color:#5bc4bf">=</span> true
</span></span><span style="display:flex;"><span>  bind-address <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;:25826&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#ef6155">database</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;collectd&#34;</span>
</span></span><span style="display:flex;"><span>  retention-policy <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#ef6155">typesdb</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;/usr/local/share/collectd&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable influxdb</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start influxdb</span>
</span></span></code></pre></div><p>Notez que ce service fonctionne seulement sur UDP. Il semble ne pas y
avoir d&rsquo;options disponibles pour TCP ni TLS.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># netstat -na | grep 25826</span>
</span></span><span style="display:flex;"><span>udp <span style="color:#f99b15">0</span> <span style="color:#f99b15">0</span> *.25826 *.*
</span></span></code></pre></div><h2 id="collecter-les-données">Collecter les données</h2>
<p>Utilisons CollectD en tant que collecteur des métriques. Surtout parce
qu&rsquo;il connaît OpenBSD et qu&rsquo;il est capable d&rsquo;envoyer ses données à
distance. Dans ce cas, à InfluxDB. Activez tous les plugins requis.</p>
<p>N&rsquo;oubliez pas celui relatif au réseau afin que les données soient
envoyées à InfluxDB.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add collectd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># vi /etc/collectd.conf</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>&lt;Plugin network&gt;
</span></span><span style="display:flex;"><span>  &lt;Server <span style="color:#48b685">&#34;127.0.0.1&#34;</span> <span style="color:#48b685">&#34;25826&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;/Server&gt;
</span></span><span style="display:flex;"><span>  ReportStats true
</span></span><span style="display:flex;"><span>&lt;/Plugin&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable collectd</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start collectd</span>
</span></span></code></pre></div><h2 id="restituer-les-données">Restituer les données</h2>
<p>Ce qui est nouveau dans la version current d&rsquo;OpenBSD 6.2 : Grafana est
disponible en tant que package. Cela permettra de faire de jolis
graphiques en utilisant OpenBSD.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pkg_add grafana</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># vi /etc/grafana/config.ini</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable grafana</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start grafana</span>
</span></span></code></pre></div><p>Ouvrez votre navigateur web à l&rsquo;adresse <code>http://localhost:3000/</code> et
connectez vous en utilisant les informations d&rsquo;identification par défaut
(<code>admin:admin</code>). Ceux-ci peuvent être modifiés de cette
<a href="http://docs.grafana.org/installation/configuration/#security" rel="external">manière</a>
et depuis l&rsquo;interface graphique.</p>
<p>Dans Grafana, ajoutez la source InfluxDB en tant que base de données.</p>
<p>Des exemples de tableaux de bord sont disponibles sur le site Web de
Grafana, tels que le #<a href="https://grafana.com/dashboards/554" rel="external">554</a>,
#[<a href="https://grafana.com/dashboards/555" rel="external">555</a> et
#<a href="https://grafana.com/dashboards/755" rel="external">755</a>. Ils seront presque prêts à
l&rsquo;emploi et peuvent servir de base pour créer les vôtres. Ils semblent
être centrés sur Linux mais voici à quoi ils ressemblent, une fois
légèrement modifiés pour OpenBSD,
<a href="https://grafana.com/dashboards/4775" rel="external">disponible sur Grafana</a>.</p>
<p>&ldquo;That’s All Folks!&rdquo;</p>
<hr>
<h2 id="remerciements">Remerciements</h2>
<p>Avec l&rsquo;aimable autorisation de Joel Carnat !</p>
<p><em>Cette page est la traduction de la page <a href="https://www.tumfatig.net/2018/monitoring-openbsd-using-collectd-influxdb-and-grafana/" rel="external">Monitoring OpenBSD using CollectD, InfluxDB and Grafana</a>
du site TUM&rsquo;FATIG. - <a href="https://www.tumfatig.net/disclaimer/" rel="external">licence de type BSD</a></em>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;Monitoring OpenBSD using CollectD, InfluxDB and Grafana&#39; de l&#39;auteur Joel Carnat]]></summary>
        <published>2018-06-09T12:04:30+02:00</published>
        <updated>2023-05-09T14:02:04+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:dbaa30b1-5f02-2d3c-aec2-d3935d20cdff</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/openbsd-dnssec-plus-dns-over-tls/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Utiliser DNSSEC, &#43; DNS / TLS (EXPÉRIMENTAL)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <category term="DoT" scheme="http://doc.huc.fr.eu.org/fr/tags/dot/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="stubby" scheme="http://doc.huc.fr.eu.org/fr/tags/stubby/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<ul>
<li>OpenBSD : 6.2</li>
</ul>
<p>Coupler des requêtes DNSSEC en utilisant &ldquo;DNS-over-TLS&rdquo; sous OpenBSD est
non seulement possible, mais envisageable, et fonctionnel…
plus ou moins nativement !</p>
<p>Pour <strong>les requêtes DNSSEC</strong>, nous avons <strong>nativement sous OpenBSD</strong> –
un outil fort puissant et utile, à savoir : <strong>&lsquo;&lsquo;unbound&rsquo;&rsquo;</strong>.</p>
<p>Unbound est capable de discuter sur la pile DualStack IPv4, IPv6 ; il nous
permet aussi de créer/d’avoir en local un resolveur cache qui nous fait
des requêtes auprès des DNS publiques, si besoin…</p>
<p>Il y a quelques mois, j’écrivais cet article sur comment <a class="inside" href="/fr/sys/openbsd/unbound/" title="Lien interne vers l&#39;article : 'OpenBSD : utiliser Unbound'">Utiliser Unbound avec DNSSEC</a>
 sur
OpenBSD. Vous l’avez lu ? Très bien, sinon faites-le…</p>
<ul>
<li>Il faudra impérativement vous familiariser et mettre en place votre
fichier de configuration, avec toutes les autres options utiles –
<em>ce n’est pas compliqué du tout</em>.</li>
<li>Assurez-vous impérativement de vérifier que vos requêtes soient correctes…</li>
</ul>
<p>Quant à la question des <strong>requêtes DNS sur TLS</strong>, hier, nous avons vu
l’<strong>usage de <a class="inside" href="/fr/sys/openbsd/stubby/" title="Lien interne vers l&#39;article : 'Stubby : Client DNS/TLS sous OpenBSD (EXPÉRIMENTAL) '">Stubby : Client DNS/TLS sous OpenBSD (EXPÉRIMENTAL) </a></strong>, lui aussi capable de
discuter sur la DualStack (IPv4, IPv6) – <em>c’est là qu’est la partie &ldquo;EXPÉRIMENTAL&rdquo;,
car non natif, ni en tant que package, ni dans les ports : du moins, pour l’instant</em>…
mais <strong>c’est vraiment fonctionnel !</strong></p>
<h2 id="créons-un-resolveur-cache-local-dnssec-avec-dnstls">Créons un resolveur cache local DNSSEC avec DNS/TLS</h2>
<p>Alors comment faire pour utiliser sur notre machine ces deux logiciels de
manière à avoir un resolveur cache local communiquant sur DNSSEC et avoir
des requêtes DNS sur TLS, dans le même laps de temps ?</p>
<p>Il semble que nous soyons obligés de coupler :</p>
<ul>
<li>unbound, bien que capable de comprendre DNSSEC, et d’utiliser un flux
SSL, semble ne pas être – <em>encore ?</em> - capable d’authentifier les flux,
de ré-utiliser les connexions TCP et TLS, d’être configuré pour le mode
Strict ou Opportun lié à l’usage de DNS/TLS , voire d’envoyer les options
relatives à cet usage confidentiel.</li>
<li>c’est justement là qu’intervient un logiciel comme stubby en complément
d’unbound. Lui est capable de faire ce que n’est pas capable unbound,
mais n’est pas fait pour être un resolveur cache, même s’il est capable
d’utiliser DNSSEC, lui aussi.</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="resolvconf">resolv.conf</h3>
<p>La première chose à s’assurer est d’avoir paramétré correctement votre fichier
<code>/etc/resolv.conf</code> pour n’interroger qu’en local !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">nameserver 127.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">nameserver ::1</span>
</span></span></code></pre></div><h3 id="unboundconf">unbound.conf</h3>
<p>Ensuite, il faut modifier légèrement votre fichier <code>/var/unbound/etc/unbound.conf</code>,
pour veiller à ajouter quelques paramètres ; il y a  :</p>
<ul>
<li>l’usage de l’option <code>do-not-query-localhost</code></li>
<li>et le fait de transmettre les requêtes non connues à notre ami <strong>stubby</strong></li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: unbound.conf,v 1.7 2016/03/30 01:41:25 sthen Exp $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">(...)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">do-not-query-localhost:  no</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">(...)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">forward-zone:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">name: &#34;.&#34;                               # use for ALL queries</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">forward-addr: ::1@853</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">forward-addr: 127.0.0.1@853</span>
</span></span></code></pre></div><p>Toute requête DNS qui n&rsquo;est pas en cache dans la mémoire d&rsquo;unbound sera
transmise à stubby qui fera le nécessaire…
unbound prendra absolument le relais pour toute requête DNS identique.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il est possible d&rsquo;utiliser tout autre port, tel que &lsquo;&lsquo;8053&rsquo;&rsquo; comme montré
en exemple sur la documentation de stubby. Quelque soit votre choix,
veillez à mettre le même port dans la configuration de stubby !</div>

<h3 id="stubbyyml">stubby.yml</h3>
<p>Il nous faut modifier le fichier de configuration de stubby <code>/usr/local/etc/stubby/stubby.yml</code>,
en rapport avec le port spécifié sur les adresses que le service de
stubby va devoir écouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">(...)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen_addresses:</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">- 127.0.0.1@853</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">-  0::1@853</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">(...)</span>
</span></span></code></pre></div><p>Si dans le fichier de configuration d&rsquo;unbound, vous utilisez un autre numéro
que celui-ci, veillez impérativement renseigner le même !</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pour information, il est envisageable de demander à stubby d&rsquo;exécuter
ses requêtes sur le protocole DNSSEC ; pour cela, il faut décommenter
l&rsquo;option <code>dnssec_return_status: GETDNS_EXTENSION_TRUE</code> !</p>
<p>Cela augmente assurément le temps de charge des requêtes. Laissez donc à
unbound le soin de les faire !</p>
<p>Dans la partie <code># Additional server</code> du fichier de configuration de stubby,
vous avez la possibilité de décommenter un ou plusieurs serveurs à interroger,
autant sur IPv4 qu&rsquo;IPv6, dont le fameux Quad9 @9999&hellip;.</p>
</div>

<h2 id="redémarrer-les-services">Redémarrer les services</h2>
<p>Si (re)démarrer LE service relatif à unbound n&rsquo;est pas bien difficile, à
coup de : <code># rcctl restart unbound</code>, (re)démarrer celui de stubby n&rsquo;est
pas possible car rien n&rsquo;existe par défaut pour que cela puisse être.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Avant de chercher à redémarrer les services, pensez d&rsquo;abord à vérifier
vos fichiers de configuration - pour rappel :</p>
<ul>
<li>pour unbound : <code>$ unbound-checkconf</code></li>
<li>pour stubby : <code>$ stubby -i</code></li>
</ul></div>

<h3 id="création-du-fichier-rc-pour-stubby">Création du fichier rc pour stubby</h3>
<p>Pour que stubby puisse interagir en tant que service sur votre système
OpenBSD, il faut lui créer un fichier <strong>rc</strong>, à positionner dans <code>/etc/rc.d/stubby</code>
avec pour contenu ceci, ni + ni - :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: stubby,v 0.2.2 2018/03/22 12:00:00 Stephane HUC $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/usr/local/bin/stubby&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">daemon_flags</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">. /etc/rc.d/rc.subr</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#rc_reload=NO</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rc_cmd $1</span>
</span></span></code></pre></div><p>Attribuez-lui des droits suivants : <code># chmod 555 /etc/rc.d/stubby</code></p>
<p>Voilà, maintenant vous allez pouvoir jouer du contrôleur rc :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl enable stubby</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl set stubby flags &#34;-g&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># rcctl start stubby</span>
</span></span></code></pre></div><h2 id="tests">Tests</h2>
<p>Très basiquement avec l&rsquo;outil <code>dig</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ dig @::1 A www.gandi.net
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.4.2-P2 &lt;&lt;&gt;&gt; @::1 www.gandi.net
</span></span><span style="display:flex;"><span>; <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> server found<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; global options:  printcmd
</span></span><span style="display:flex;"><span>;; Got answer:
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">12892</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; QUESTION SECTION:
</span></span><span style="display:flex;"><span>;www.gandi.net.                 IN      A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; ANSWER SECTION:
</span></span><span style="display:flex;"><span>www.gandi.net.          <span style="color:#f99b15">46710</span>   IN      CNAME   prod.gandi.map.fastly.net.
</span></span><span style="display:flex;"><span>prod.gandi.map.fastly.net. <span style="color:#f99b15">3600</span> IN      A       151.101.37.103
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; Query time: <span style="color:#f99b15">644</span> msec
</span></span><span style="display:flex;"><span>;; SERVER: ::1#53<span style="color:#5bc4bf">(</span>::1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; WHEN: Fri Mar <span style="color:#f99b15">23</span> 01:17:20 <span style="color:#f99b15">2018</span>
</span></span><span style="display:flex;"><span>;; MSG SIZE  rcvd: <span style="color:#f99b15">83</span>
</span></span></code></pre></div><p>On la réitère pour se rendre compte de la différence en terme de temps d&rsquo;accès :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ dig @::1 www.gandi.net 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.4.2-P2 &lt;&lt;&gt;&gt; @::1 www.gandi.net
</span></span><span style="display:flex;"><span>; <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> server found<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; global options:  printcmd
</span></span><span style="display:flex;"><span>;; Got answer:
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">2032</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; QUESTION SECTION:
</span></span><span style="display:flex;"><span>;www.gandi.net.                 IN      A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; ANSWER SECTION:
</span></span><span style="display:flex;"><span>www.gandi.net.          <span style="color:#f99b15">46706</span>   IN      CNAME   prod.gandi.map.fastly.net.
</span></span><span style="display:flex;"><span>prod.gandi.map.fastly.net. <span style="color:#f99b15">3596</span> IN      A       151.101.37.103
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; Query time: <span style="color:#f99b15">1</span> msec
</span></span><span style="display:flex;"><span>;; SERVER: ::1#53<span style="color:#5bc4bf">(</span>::1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; WHEN: Fri Mar <span style="color:#f99b15">23</span> 01:17:24 <span style="color:#f99b15">2018</span>
</span></span><span style="display:flex;"><span>;; MSG SIZE  rcvd: <span style="color:#f99b15">83</span>
</span></span></code></pre></div><p><strong>644</strong> millisecondes la première interrogation ; <strong>1</strong> milliseconde, la seconde…
unbound fait son travail de cache assurément !</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>La <a href="https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Project+Homepage" rel="external">documentation</a> de stubby,
sa <a href="https://dnsprivacy.org/wiki/display/DP/About+Stubby" rel="external">FAQ</a> et sa
partie de <a href="https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Clients" rel="external">configuration avec un resolveur cache local</a></li>
<li>La <a href="https://unbound.net/documentation/unbound.conf.html" rel="external">documentation</a> d&rsquo;unbound</li>
<li>Stephane Bortzmeyer explique certaines choses à ce propos [<a href="http://www.bortzmeyer.org/quad9.html" rel="external">ici</a>
et <a href="http://www.bortzmeyer.org/7858.html" rel="external">là</a>… par exemple !</li>
</ul>
<hr>
]]></content>
        
        <published>2018-03-23T19:30:19+02:00</published>
        <updated>2022-04-22T20:34:11+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ce93ab32-b7c1-03c4-0b06-f9afd574d6d2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/stubby/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Stubby : Client DNS/TLS sous OpenBSD (EXPÉRIMENTAL) </title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="stubby" scheme="http://doc.huc.fr.eu.org/fr/tags/stubby/" />
        <category term="experimental" scheme="http://doc.huc.fr.eu.org/fr/tags/experimental/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DoT" scheme="http://doc.huc.fr.eu.org/fr/tags/dot/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><a href="https://github.com/getdnsapi/stubby" rel="external">Stubby</a> est une application qui agit en
tant que client DNS, sur protocole sécurisé (en utilisant 




















<span lang="en">DoT <em>(DNS-over-TCP)</em></span>


























































































). <br>
Ce logiciel chiffre les requêtes DNS envoyées d&rsquo;une machine cliente vers
un résolveur DNS, ou un serveur DNS faisant autorité afin d&rsquo;augmenter la
confidentialité des communications de l&rsquo;utilisateur, par le chiffrement
des requêtes DNS. <br>
De même, il peut faire des requêtes DNS selon le protocole DNSSEC.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Attention : il ne fait pas office de résolveur cache DNS, ni de serveur
faisant autorité ; ce n&rsquo;est qu&rsquo;un client DNS !</p>
<p>De plus, il n&rsquo;existe ni package, ni port de
Stubby sous OpenBSD stable… et encore moins de port officiel du
projet stubbly vers OpenBSD, d&rsquo;où le titre &ldquo;EXPÉRIMENTAL&rdquo;. Nous allons
devoir récupérer les sources, les compiler, installer, configurer,
etc…</p>
</div>

<h2 id="installation">Installation</h2>
<p>L&rsquo;installation du client <strong>stubby</strong> se fait/fera sous OpenBSD stable.</p>
<ul>
<li>la 6.3 à ce jour…</li>
</ul>
<h3 id="pré-requis">Pré-requis</h3>
<ul>
<li><code>OpenSSL</code> : installé par défaut</li>
<li><code>Libyaml</code> : à installer…</li>
<li><code>autoconf</code>, <code>automake</code> : à installer pour les phases de configuration, 
compilation avant installation</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# pkg_add autoconf automake libyaml
</span></span><span style="display:flex;"><span>quirks-2.414 signed on 2018-03-28T14:24:37Z
</span></span><span style="display:flex;"><span>Ambiguous: choose package <span style="color:#815ba4">for</span> autoconf
</span></span><span style="display:flex;"><span>a       0: &lt;None&gt;
</span></span><span style="display:flex;"><span>        1: autoconf-2.13p4
</span></span><span style="display:flex;"><span>        2: autoconf-2.52p6
</span></span><span style="display:flex;"><span>        3: autoconf-2.54p5
</span></span><span style="display:flex;"><span>        4: autoconf-2.56p4
</span></span><span style="display:flex;"><span>        5: autoconf-2.57p4
</span></span><span style="display:flex;"><span>        6: autoconf-2.58p5
</span></span><span style="display:flex;"><span>        7: autoconf-2.59p5
</span></span><span style="display:flex;"><span>        8: autoconf-2.60p5
</span></span><span style="display:flex;"><span>        9: autoconf-2.61p5
</span></span><span style="display:flex;"><span>        10: autoconf-2.62p2
</span></span><span style="display:flex;"><span>        11: autoconf-2.63p1
</span></span><span style="display:flex;"><span>        12: autoconf-2.64p1
</span></span><span style="display:flex;"><span>        13: autoconf-2.65p1
</span></span><span style="display:flex;"><span>        14: autoconf-2.67p1
</span></span><span style="display:flex;"><span>        15: autoconf-2.68p1
</span></span><span style="display:flex;"><span>        16: autoconf-2.69p2
</span></span><span style="display:flex;"><span>Your choice: <span style="color:#f99b15">16</span>
</span></span><span style="display:flex;"><span>Ambiguous: choose package <span style="color:#815ba4">for</span> automake
</span></span><span style="display:flex;"><span>a       0: &lt;None&gt;
</span></span><span style="display:flex;"><span>        1: automake-1.10.3p8
</span></span><span style="display:flex;"><span>        2: automake-1.11.6p2
</span></span><span style="display:flex;"><span>        3: automake-1.12.6p1
</span></span><span style="display:flex;"><span>        4: automake-1.13.4p1
</span></span><span style="display:flex;"><span>        5: automake-1.14.1p0
</span></span><span style="display:flex;"><span>        6: automake-1.15.1
</span></span><span style="display:flex;"><span>        7: automake-1.4.6p5
</span></span><span style="display:flex;"><span>        8: automake-1.8.5p9
</span></span><span style="display:flex;"><span>        9: automake-1.9.6p12
</span></span><span style="display:flex;"><span>Your choice: <span style="color:#f99b15">6</span>
</span></span></code></pre></div><p>Puis on va suivre les recommandations officielles
d&rsquo;<a href="https://dnsprivacy.org/wiki/pages/viewpage.action?pageId=3145786" rel="external">installation depuis les sources</a></p>
<ul>
<li><em>pour Linux</em> - en les adaptant à notre cher OS qu&rsquo;est OpenBSD.
Chacune des étapes est à exécuter l&rsquo;une après l&rsquo;autre.</li>
</ul>
<h3 id="téléchargement">Téléchargement</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ git clone https://github.com/getdnsapi/getdns.git
</span></span><span style="display:flex;"><span>:$ cd getdns
</span></span><span style="display:flex;"><span>:$ git checkout develop
</span></span></code></pre></div><p>La deuxième commande <em>git</em> nous permet d&rsquo;obtenir les sources les plus
récentes…</p>
<h3 id="configuration">Configuration</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ git submodule update --init
</span></span><span style="display:flex;"><span>:$ libtoolize -ci
</span></span><span style="display:flex;"><span>:$ export <span style="color:#ef6155">AUTOCONF_VERSION</span><span style="color:#5bc4bf">=</span>2.69
</span></span><span style="display:flex;"><span>:$ export <span style="color:#ef6155">AUTOMAKE_VERSION</span><span style="color:#5bc4bf">=</span>1.15
</span></span><span style="display:flex;"><span>:$ autoreconf -fi
</span></span><span style="display:flex;"><span>:$ mkdir build <span style="color:#5bc4bf">&amp;&amp;</span> cd build
</span></span><span style="display:flex;"><span>:$ ../configure --prefix<span style="color:#5bc4bf">=</span>/usr/local --without-libidn --enable-stub-only --with-stubby
</span></span></code></pre></div><h3 id="compilation">Compilation</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ make
</span></span><span style="display:flex;"><span>:# make install
</span></span></code></pre></div><p>Bien-sûr, à la place de la dernière commande, si vous avez configuré
<em>
<a class="man" href="https://man.openbsd.org/doas" title="Page du Manuel OpenBSD pour : doas">doas</a>
</em>, vous pouvez ainsi l&rsquo;exécuter : <br>
<code>:$ doas make install</code></p>
<h3 id="resolvconf">resolv.conf</h3>
<p>Il est nécessaire de modifier votre fichier <code>/etc/resolv.conf</code> afin de
communiquer directement avec stubby :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">nameserver 127.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">nameserver ::1</span>
</span></span></code></pre></div><h3 id="stubbyyml">stubby.yml</h3>
<p>Le fichier de configuration de stubby se trouve être dans
<code>/usr/local/etc/stubby/stubby.yml</code>. Si vous en créez un au format yaml
dans votre répertoire personnel, tel que <code>~/.stubby.yml</code>, il sera lu en
premier.</p>
<h2 id="exécution">Exécution</h2>
<p>Pour exécuter stubby, il suffit de :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# stubby
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.896254<span style="color:#5bc4bf">]</span> STUBBY: Read config from file /usr/local/etc/stubby/stubby.yml
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898479<span style="color:#5bc4bf">]</span> STUBBY: DNSSEC Validation is OFF
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898585<span style="color:#5bc4bf">]</span> STUBBY: Transport list is:
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898617<span style="color:#5bc4bf">]</span> STUBBY:   - TLS
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898681<span style="color:#5bc4bf">]</span> STUBBY: Privacy Usage Profile is Strict <span style="color:#5bc4bf">(</span>Authentication required<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898713<span style="color:#5bc4bf">]</span> STUBBY: <span style="color:#5bc4bf">(</span>NOTE a Strict Profile only applies when TLS is the ONLY transport!!<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>12:57:39.898749<span style="color:#5bc4bf">]</span> STUBBY: Starting DAEMON....
</span></span></code></pre></div><p>Quelques informations intéressantes :</p>
<ul>
<li>le drapeau <code>-C</code> permet de spécifier un autre fichier de configuration, 
à la place de l&rsquo;original.</li>
<li>le drapeau <code>-g</code> permet de fonctionner en arrière plan…</li>
<li>le drapeau <code>-i</code> permet de vérifier la configuration !</li>
<li>le drapeau <code>-l</code> a pour objectif de journaliser les connexions. 
Pour l&rsquo;instant, la sortie se fait sur la sortie standard <code>stdout</code> !</li>
</ul>
<h3 id="test">Test</h3>
<p>L&rsquo;usage très simple de <code>dig</code> nous permettra de nous assurer du bon
fonctionnement :</p>
<p>⇒ Version IPv4</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ dig @127.0.0.1 www.gandi.net
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.4.2-P2 &lt;&lt;&gt;&gt; @127.0.0.1 www.gandi.net
</span></span><span style="display:flex;"><span>; <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> server found<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; global options:  printcmd
</span></span><span style="display:flex;"><span>;; Got answer:
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">40041</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; QUESTION SECTION:
</span></span><span style="display:flex;"><span>;www.gandi.net.                 IN      A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; ANSWER SECTION:
</span></span><span style="display:flex;"><span>www.gandi.net.          <span style="color:#f99b15">21583</span>   IN      CNAME   prod.gandi.map.fastly.net.
</span></span><span style="display:flex;"><span>prod.gandi.map.fastly.net. <span style="color:#f99b15">3600</span> IN      A       151.101.37.103
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; AUTHORITY SECTION:
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">3600</span>    IN      NS      ns1.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">3600</span>    IN      NS      ns2.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">3600</span>    IN      NS      ns3.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">3600</span>    IN      NS      ns4.fastly.net.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; Query time: <span style="color:#f99b15">1888</span> msec
</span></span><span style="display:flex;"><span>;; SERVER: 127.0.0.1#53<span style="color:#5bc4bf">(</span>127.0.0.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; WHEN: Thu Mar <span style="color:#f99b15">22</span> 14:15:51 <span style="color:#f99b15">2018</span>
</span></span><span style="display:flex;"><span>;; MSG SIZE  rcvd: <span style="color:#f99b15">155</span>
</span></span></code></pre></div><p>⇒ Version IPv6 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ dig @::1 www.gandi.net
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.4.2-P2 &lt;&lt;&gt;&gt; @::1 www.gandi.net
</span></span><span style="display:flex;"><span>; <span style="color:#5bc4bf">(</span><span style="color:#f99b15">1</span> server found<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; global options:  printcmd
</span></span><span style="display:flex;"><span>;; Got answer:
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">24688</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; QUESTION SECTION:
</span></span><span style="display:flex;"><span>;www.gandi.net.                 IN      A
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; ANSWER SECTION:
</span></span><span style="display:flex;"><span>www.gandi.net.          <span style="color:#f99b15">84574</span>   IN      CNAME   prod.gandi.map.fastly.net.
</span></span><span style="display:flex;"><span>prod.gandi.map.fastly.net. <span style="color:#f99b15">3600</span> IN      A       151.101.85.103
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; AUTHORITY SECTION:
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">168207</span>  IN      NS      ns4.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">168207</span>  IN      NS      ns2.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">168207</span>  IN      NS      ns1.fastly.net.
</span></span><span style="display:flex;"><span>fastly.net.             <span style="color:#f99b15">168207</span>  IN      NS      ns3.fastly.net.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; ADDITIONAL SECTION:
</span></span><span style="display:flex;"><span>ns1.fastly.net.         <span style="color:#f99b15">3600</span>    IN      A       23.235.32.32
</span></span><span style="display:flex;"><span>ns2.fastly.net.         <span style="color:#f99b15">3600</span>    IN      A       104.156.80.32
</span></span><span style="display:flex;"><span>ns3.fastly.net.         <span style="color:#f99b15">3600</span>    IN      A       23.235.36.32
</span></span><span style="display:flex;"><span>ns4.fastly.net.         <span style="color:#f99b15">3600</span>    IN      A       104.156.84.32
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>;; Query time: <span style="color:#f99b15">1614</span> msec
</span></span><span style="display:flex;"><span>;; SERVER: ::1#53<span style="color:#5bc4bf">(</span>::1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>;; WHEN: Thu Mar <span style="color:#f99b15">22</span> 14:16:40 <span style="color:#f99b15">2018</span>
</span></span><span style="display:flex;"><span>;; MSG SIZE  rcvd: <span style="color:#f99b15">219</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Expérimentation d&#39;installation de stubby, un client DoT pour DNS, et DNSSEC, sur OpenBSD (6.3).]]></summary>
        <published>2018-03-22T14:21:09+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3323f855-c6ef-1682-012a-9d0139625a74</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/generer-enregistrement-tlsa/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: DNS: Générer un enregistrement TLSA</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="DANE" scheme="http://doc.huc.fr.eu.org/fr/tags/dane/" />
        <category term="TLSA" scheme="http://doc.huc.fr.eu.org/fr/tags/tlsa/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Du fait de gérer moi-même la zone DNS pour mon propre ndd, dans le but
&ldquo;d&rsquo;implémenter&rdquo; DNSSEC.</p>
<p>Je commence maintenant à m&rsquo;intéresser aux enregistrements DANE. Pour
l&rsquo;instant, je ne génère qu&rsquo;un enregistrement pour le port 443/tcp - service web.
Mais il est possible d&rsquo;en générer pour d&rsquo;autres services, tel que 25/tcp
qui correspond à smtp, d&rsquo;autres protocoles que tcp, etc…</p>
<p>Créer un enregistrement TLSA n&rsquo;est pas compliqué !</p>
<p>Pour le propos, un enregistrement TLSA est ainsi construit :</p>
<p><code>_numeroDePort._protocol.domain. IN TLSA usage selecteur correspondance certificatAssocie</code></p>
<p><em>Veuillez consulter la <a href="/fr/post/generer-enregistrement-tlsa/#documentation">documentation</a> de l&rsquo;Afnic, ci-dessous,
pour bien comprendre le propos.</em></p>
<h2 id="génération-tlsa-en-shell">Génération TLSA en shell</h2>
<p>Pour générer un enregistrement TLSA en shell, c&rsquo;est assez simple en somme :</p>
<p><code>openssl x509 -noout -pubkey -in /etc/ssl/acme/nomDeDomaine.cert.pem | openssl rsa -pubin -outform der 2&gt;/dev/null | sha512 | tr &quot;a-z&quot; &quot;A-Z&quot;</code></p>
<p>Dans un premier temps :</p>
<ul>
<li>on choisit l&rsquo;algo, soit sha256, soit sha512</li>
<li>on choisit de n&rsquo;utiliser tout le certificat ou juste la clé publique de celui-ci</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#ef6155">algo</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;sha512&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">domain</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;stephane-huc.net&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">cert</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;/etc/ssl/acme/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">.cert.pem&#34;</span>    <span style="color:#776e71"># chemin vers le fichier cert SSL généré par LetsEncrypt, avec le client natif OpenBSD - acme secure !</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tls_port</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">443</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tls_proto</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;tcp&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span>    <span style="color:#776e71"># Usage Field; possible: 0 =&gt; 3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_selector</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#776e71"># Selector Field; 0: use cert; 1: use public key</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>   <span style="color:#776e71"># Matching Type Field</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;sha256&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;sha512&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> ;;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#tlsa_cert_associated=&#34;$(openssl x509 -in &#34;${cert}&#34; -outform der | openssl $algo | cut -d &#39; &#39; -f2)&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>openssl x509 -noout -pubkey -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl rsa -pubin -outform der 2&gt;/dev/null | <span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span> | tr <span style="color:#48b685">&#34;a-z&#34;</span> <span style="color:#48b685">&#34;A-Z&#34;</span> <span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_record</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ajout de l&#39;enregistrement vers votre zone dns ; dans ce cas, l&#39;enregistrement de cette dernière est dû au fait de l&#39;outil ldnscript de @&#34;22decembre&#34; !</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> &gt;&gt; /etc/ns/<span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span>
</span></span></code></pre></div><h3 id="version-multi-domaines">Version multi-domaines</h3>
<p>Voici le même code shell, pour gérer plusieurs domaines, pour exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">algo</span><span style="color:#5bc4bf">=</span>sha256
</span></span><span style="display:flex;"><span><span style="color:#776e71">#cert=&#34;/etc/ssl/acme/${domain}.cert.pem&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">domains</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;yeuxdelibad.net 3hg.fr ouaf.xyz&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tls_proto</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;tcp&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tls_ports</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;443&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_usage</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">3</span>    <span style="color:#776e71"># Usage Field; possible: 0 =&gt; 3</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_selector</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> <span style="color:#776e71"># Selector Field; 0: use cert; 1: use public key</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>   <span style="color:#776e71"># Matching Type Field</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;sha256&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span> ;;
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;sha512&#34;</span><span style="color:#5bc4bf">)</span> <span style="color:#ef6155">tlsa_method</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> ;;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">for</span> domain in <span style="color:#f99b15">${</span><span style="color:#ef6155">domains</span><span style="color:#f99b15">}</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">cert</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;etc/ssl/acme/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">.cert.pem&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>openssl x509 -noout -pubkey -in <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">cert</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl rsa -pubin -outform der 2&gt;/dev/null | <span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span> | tr <span style="color:#48b685">&#34;a-z&#34;</span> <span style="color:#48b685">&#34;A-Z&#34;</span> <span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> port in <span style="color:#f99b15">${</span><span style="color:#ef6155">tls_ports</span><span style="color:#f99b15">}</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">tlsa_record</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;_</span><span style="color:#f99b15">${</span><span style="color:#ef6155">port</span><span style="color:#f99b15">}</span><span style="color:#48b685">._</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tls_proto</span><span style="color:#f99b15">}</span><span style="color:#48b685">.</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">. IN TLSA </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_usage</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_selector</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_method</span><span style="color:#f99b15">}</span><span style="color:#48b685"> </span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_cert_associated</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">tlsa_record</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> &gt;&gt; <span style="color:#48b685">&#34;/etc/ns/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#48b685">&#34;You should update your </span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685"> zone in 48h&#34;</span> | mail -s <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">domain</span><span style="color:#f99b15">}</span><span style="color:#48b685"> TLSA update&#34;</span> root
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    sleep <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># reload zone and nsd ; à décommenter, si vous utiliser nsd ;)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#/var/ldns/ldnscript signing &#34;${domain}&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">done</span>
</span></span></code></pre></div><p><em>Merci <a href="https://si3t.ch" rel="external">Xavier</a> ;)</em></p>
<h2 id="générer-tlsa-en-php">Générer TLSA en PHP</h2>
<p>Générer un enregistrement TLSA en PHP n&rsquo;est guère plus compliqué, à
partir du moment où on a les bonnes infos !</p>
<p>On veille à récupérer le certificat au format PEM, à l&rsquo;injecter dans un
formulaire HTML et à traiter les informations reçues par celui-ci.
<em>Je ne décris pas le code HTML</em>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;?</span><span style="color:#06b6ef">php</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> <span style="color:#06b6ef">extractPublicKey</span>(<span style="color:#ef6155">$cert</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$certificate</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">openssl_x509_read</span>(<span style="color:#ef6155">$cert</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$pub_key</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">openssl_get_publickey</span>(<span style="color:#ef6155">$certificate</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$pub_key</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">openssl_pkey_get_details</span>(<span style="color:#ef6155">$pub_key</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> (<span style="color:#5bc4bf">!</span><span style="color:#06b6ef">isset</span>(<span style="color:#ef6155">$pub_key</span>[<span style="color:#48b685">&#39;key&#39;</span>])) {
</span></span><span style="display:flex;"><span>      <span style="color:#776e71">// @codeCoverageIgnoreStart
</span></span></span><span style="display:flex;"><span>      <span style="color:#815ba4">throw</span> <span style="color:#815ba4">new</span> <span style="color:#06b6ef">\InvalidArgumentException</span>(<span style="color:#48b685">&#39;Provided certificate is invalid.&#39;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#776e71">// @codeCoverageIgnoreEnd
</span></span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#ef6155">$pub_key</span>[<span style="color:#48b685">&#39;key&#39;</span>];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> <span style="color:#06b6ef">pem2der</span>(<span style="color:#ef6155">$pem</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#06b6ef">base64_decode</span>(<span style="color:#06b6ef">str_replace</span>([<span style="color:#48b685">&#34;</span><span style="color:#f99b15">\n</span><span style="color:#48b685">&#34;</span>, <span style="color:#48b685">&#34;</span><span style="color:#f99b15">\r</span><span style="color:#48b685">&#34;</span>], <span style="color:#48b685">&#39;&#39;</span>, <span style="color:#ef6155">$pem</span>));
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> <span style="color:#06b6ef">stripDatas</span>(<span style="color:#ef6155">$pem</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$datas</span> <span style="color:#5bc4bf">=</span> [
</span></span><span style="display:flex;"><span>      <span style="color:#48b685">&#39;-----BEGIN PUBLIC KEY-----&#39;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#48b685">&#39;-----END PUBLIC KEY-----&#39;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#48b685">&#39;-----BEGIN CERTIFICATE-----&#39;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#48b685">&#39;-----END CERTIFICATE-----&#39;</span>
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">$data</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">str_replace</span>(<span style="color:#ef6155">$datas</span>, <span style="color:#48b685">&#39;&#39;</span>, <span style="color:#ef6155">$pem</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#06b6ef">trim</span>(<span style="color:#ef6155">$data</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $datas = certificat au format PEM
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$pkey</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">extractPublicKey</span>(<span style="color:#ef6155">$datas</span>);
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$pem</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">pem2der</span>(<span style="color:#06b6ef">stripDatas</span>(<span style="color:#ef6155">$pkey</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">switch</span>(<span style="color:#ef6155">$tlsa_match</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#f99b15">0</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$data</span> <span style="color:#5bc4bf">=</span> <span style="color:#ef6155">$pem</span>; <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#f99b15">1</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$data</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">hash</span>(<span style="color:#48b685">&#39;sha256&#39;</span>, <span style="color:#ef6155">$pem</span>, <span style="color:#815ba4">true</span>); <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#f99b15">2</span><span style="color:#5bc4bf">:</span> <span style="color:#ef6155">$data</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">hash</span>(<span style="color:#48b685">&#39;sha512&#39;</span>, <span style="color:#ef6155">$pem</span>, <span style="color:#815ba4">true</span>); <span style="color:#815ba4">break</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">$tlsa_cert_associated</span> <span style="color:#5bc4bf">=</span> <span style="color:#06b6ef">bin2hex</span>(<span style="color:#ef6155">$data</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># les variables $port, $protocol, $domain ainsi que les $tlsa_* sont des variables créées dans le contexte du formulaire HTML, et nommées très simplement selon leur contexte.
</span></span></span><span style="display:flex;"><span><span style="color:#ef6155">$tlsa_gen</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;_&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$port</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;._&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$protocol</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;.&#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$domain</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34;. IN TLSA &#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$tlsa_usage</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34; &#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$tlsa_selector</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34; &#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$tlsa_match</span><span style="color:#5bc4bf">.</span><span style="color:#48b685">&#34; &#34;</span><span style="color:#5bc4bf">.</span><span style="color:#ef6155">$tlsa_cert_associated</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># pour finir, un echo là où vous le désirez dans votre code HTML de restitution...
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">echo</span> <span style="color:#ef6155">$tlsa_gen</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">?&gt;</span><span style="color:#ef6155">
</span></span></span></code></pre></div><p><em>Les fonctions dans le code ne sont pas de moi - je partage ni + ni -</em></p>
<h2 id="vérification-de-lenregistrement-tlsa">Vérification de l&rsquo;enregistrement TLSA</h2>
<p>Il existe des modules à Firefox :</p>
<ul>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/dnssec/?src=api" rel="external">DNSSEC</a></li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/dnssec-dane-validator/" rel="external">DNSSEC/DANE Validator</a></li>
</ul>
<p>On peut le faire par l&rsquo;usage de générateur TLSA en ligne - puis comparer les infos restituées avec celles que vous avez générées - <em>malheureusement rien d&rsquo;automati(que|sé)</em> :</p>
<ul>
<li>celui de <a href="https://www.huque.com/bin/gen_tlsa" rel="external">Simon Huque</a></li>
<li>celui de <a href="https://ssl-tools.net/tlsa-generator" rel="external">SSL-Tools</a></li>
<li>et forcément <a href="https://huc.fr.eu.org/tools/dane-tlsa.php" rel="external">le mien</a> - <em>le seul en français !?</em></li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>L&rsquo;afnic a écrit des articles intéressants à-propos de :</p>
<ul>
<li><a href="https://www.afnic.fr/medias/documents/afnic-dossier-dnssec-2010-09.pdf" rel="external">DNSSEC</a></li>
<li><a href="http://www.afnic.fr/fr/ressources/publications/dossiers-thematiques/securiser-les-communications-sur-internet-de-bout-en-bout-avec-le-protocole-dane.html" rel="external">DANE</a></li>
</ul>
<p>Stéphane Bortzmeyer aussi parle de la <a href="http://www.bortzmeyer.org/6698.html" rel="external">RFC 6698</a> et explique beaucoup de choses intéressantes !</p>
<p>Un autre <a href="https://www.abyssproject.net/2016/09/creer-utiliser-enregistrements-tlsa-dane/" rel="external">article</a> expliquant de manière claire, simple DANE-TLSA.</p>
<hr>
<p>Voilà !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment générer un enregistrement TLSA en langage shell, et PHP]]></summary>
        <published>2018-03-19T16:03:53+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:39e14619-2d31-e3f7-6721-9a71e9018ae2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-erreurs/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : les messages d&#39;erreurs</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Cet article répertorie les différentes erreurs plus ou moins classiques,
et essaie d&rsquo;apporter une réponse !</p>
<h2 id="messages">Messages</h2>
<h3 id="attention-les-droits-du-répertoire-personnel-gnupg-ne-sont-pas-sûrs">Attention : les droits du répertoire personnel « ~/.gnupg » ne sont pas sûrs</h3>
<p>Faites à minima un <em>chmod 0600</em> dessus : <br>
<code>$ chmod 0600 ~/.gnupg</code></p>
<h3 id="error-cannot-run-gpg-no-such-file-or-directory">error: cannot run gpg: No such file or directory</h3>
<p><code>error: cannot run gpg: No such file or directory </code>error: impossible de lancer gpg.`</p>
<p>Le système ne trouve pas l&rsquo;outil <strong>GPG</strong>.
<span class="red">Vérifiez votre installation</span>
…</p>
<h3 id="gpg-échec-de-la-signature--inappropriate-ioctl-for-device">gpg: échec de la signature : Inappropriate ioctl for device</h3>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">gpg: échec de la signature : Inappropriate ioctl for device
gpg: signing failed: Inappropriate ioctl for device
</code></pre><p><span class="red">Vérifiez</span>
 que les paquets <code>pinentry</code>, et/ou ses
variantes pour <strong>gtk</strong> sous Linux, *BSD soient installés : <code>pinentry-gtk2</code>,
<code>pinentry-gtk3</code> <br>
Sinon, faites-le !</p>
<h3 id="gpg-failed-to-start-the-dirmngr">gpg: failed to start the dirmngr</h3>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">gpg: failed to start the dirmngr &#39;/usr/bin/dirmngr&#39;: Aucun fichier ou dossier de ce type
gpg: connecting dirmngr at &#39;/tmp/apt-key-gpghome.fPXOnUY2mr/S.dirmngr&#39; failed: Aucun fichier ou dossier de ce type
gpg: keyserver receive failed: Pas de dirmngr
</code></pre><p><span class="red">Vérifiez</span>
  que le paquet <strong>dirmgnr</strong> soit installé ;
sinon, faites-le !</p>
<h3 id="gpg-des-parties-de-la-clef-secrète-ne-sont-pas-disponibles">gpg: des parties de la clef secrète ne sont pas disponibles</h3>
<p><strong>La clé que vous cherchez à utiliser ou avec laquelle vous cherchez à signer
est en mode &ldquo;protégé&rdquo;.</strong></p>
<p>Le seul moyen que j&rsquo;ai trouvé est de supprimer la clé
en question :</p>
<pre tabindex="0"><code>:$ gpg --delete-secret-and-public-key
gpg (GnuPG) 1.4.21; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


sec  4096R/*** 2016-03-28 Nom Prenom &lt;email@domain.tld&gt;

Faut-il supprimer cette clef du porte-clefs ? (o/N) o
C&#39;est une clef secrète — faut-il vraiment la supprimer ? (o/N) o

pub  4096R/*** 2016-03-28 Nom Prenom &lt;email@domain.tld&gt;

Faut-il supprimer cette clef du porte-clefs ? (o/N) o
</code></pre><p>Puis de réimporter le fichier de signature de clé privée que vous avez
créé suite à la création de ladite clé :</p>
<pre tabindex="0"><code>:$ gpg --import ~/email@domain.tld.private_key.asc
gpg: clef *** : clef secrète importée
gpg: clef *** : clef publique « Nom Prenom &lt;email@domain.tld&gt; » importée
gpg:       Quantité totale traitée : 1
gpg:                     importées : 1  (RSA: 1)
gpg:           clefs secrètes lues : 1
gpg:      clefs secrètes importées : 1
</code></pre><h2 id="gpg-agent--erreurs">gpg-agent :: erreurs</h2>
<h3 id="gpg-gpg-agent-nest-pas-disponible-dans-cette-session">gpg: gpg-agent n&rsquo;est pas disponible dans cette session</h3>
<p>Avez-vous veillé à <a href="https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html" rel="external">exporter la variable GPG_TTY</a> ?</p>
<p>Ajoutez dans votre fichier <code>.bashrc</code>, ou <code>.kshrc</code> :</p>
<p><code>export GPG_TTY=&quot;$(tty)&quot;</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Du traitement des messages d&#39;erreurs de GPG, et du client gpg-agent]]></summary>
        <published>2018-03-04T18:55:50+01:00</published>
        <updated>2019-03-17T18:29:50+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:df2875a5-7866-0ce1-7b04-563e1c1d76a7</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/urbackup-client-gui/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Urbackup: Client graphique pour Debian/Ubuntu</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="Urbackup" scheme="http://doc.huc.fr.eu.org/fr/tags/urbackup/" />
        <category term="backup" scheme="http://doc.huc.fr.eu.org/fr/tags/backup/" />
        <category term="GUI" scheme="http://doc.huc.fr.eu.org/fr/tags/gui/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Ceci est un tutoriel pour utiliser l&rsquo;interface graphique du logiciel client
d&rsquo;Urbackup - logiciel de sauvegarde sur serveur -</p>
<p>La première erreur à ne pas commettre est de bien télécharger le bon client :</p>
<ul>
<li><span class="red">ne pas télécharger</span>
 <del><a href="https://www.urbackup.org/download.html#linux_all_binary" rel="external">Binary Linux client (command line only; with auto-update; x86/AMD64/ARMv6+/ARM64)</a></del></li>
<li>mais bel et bien selon la page &ldquo;<strong><a href="https://www.urbackup.org/client_debian_ubuntu_install.html" rel="external">Install client on Debian or Ubuntu from sources</a></strong>&rdquo; -
ceci est en fait une traduction principalement, avec quelques corrections et aperçus !</li>
</ul>
<p>Nécessite :</p>
<ul>
<li>que le logiciel urbackup-serveur soit installé sur le serveur qui recevra
les sauvegardes du client, qu&rsquo;il soit activé et fonctionnel -
<em>ce tuto ne traite pas de l&rsquo;installation de celui-ci sur le serveur</em>.</li>
<li>le binaire <code>gksu</code> doit être installé sur la station à sauvegarder…</li>
</ul>
<h2 id="installation">Installation</h2>
<ul>
<li>Installation des dépendances nécessaires :</li>
</ul>
<pre tabindex="0"><code>:# apt install build-essential &#34;g++&#34; libwxgtk3.0-dev &#34;libcrypto++-dev&#34; libz-dev
</code></pre><ul>
<li>On télécharge puis on décompresse l&rsquo;archive relative au binaire :</li>
</ul>
<pre tabindex="0"><code>:$ wget https://hndl.urbackup.org/Client/2.1.17/urbackup-client-2.1.17.tar.gz
:$ tar xzf urbackup-client-2.1.17.tar.gz
</code></pre><ul>
<li>On compile et installe le binaire :</li>
</ul>
<pre tabindex="0"><code>:$ cd urbackup-client-2.1.17
:$ ./configure
:$ make -j4
:# make install
</code></pre><ul>
<li>Ceci étant fait, on vérifie que le service d&rsquo;arrière plan fonctionne bien :</li>
</ul>
<pre tabindex="0"><code>:$ urbackupclientbackend -v info
2018-02-15 18:22:00: Started UrBackupClient Backend…
2018-02-15 18:22:01: Looking for old Sessions… 0 sessions
</code></pre><h3 id="systemd">Systemd</h3>
<ul>
<li>Création du service de démarrage pour <strong>systemd</strong>, par l&rsquo;ajout au système
d&rsquo;un nouveau fichier nommé <code>/etc/systemd/system/urbackup.service</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Description</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">Urbackup Backend</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ConditionPathExists</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">/usr/local/sbin/urbackupclientbackend</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[Service]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">forking</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ExecStart</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">/usr/local/sbin/urbackupclientbackend -d</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">PIDFile</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">/var/run/urbackup_srv.pid</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">TimeoutSec</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[Install]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">WantedBy</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">multi-user.target</span>
</span></span></code></pre></div><ul>
<li>Lui attribuer les droits d&rsquo;exécution nécessaires :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# chmod a+x /etc/systemd/system/urbackup.service<span style="color:#48b685">`</span>
</span></span></code></pre></div><ul>
<li>Redémarrer systemd, de démarrer le nouveau service et de l&rsquo;activer pour
le démarrage automatique :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# systemctl --system daemon-reload
</span></span><span style="display:flex;"><span>:# systemctl start urbackup.service
</span></span><span style="display:flex;"><span>:# systemctl enable urbackup.service
</span></span></code></pre></div><ul>
<li>Puis, vérifier que le nouveau service fonctionne bien :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71"># systemctl status urbackup.service</span>
</span></span><span style="display:flex;"><span>● urbackup.service - Urbackup Backend
</span></span><span style="display:flex;"><span>   Loaded: loaded <span style="color:#5bc4bf">(</span>/etc/systemd/system/urbackup.service; enabled; vendor preset: enabled<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   Active: active <span style="color:#5bc4bf">(</span>running<span style="color:#5bc4bf">)</span> since Thu 2018-02-15 17:33:37 CET; 4min 5s ago
</span></span><span style="display:flex;"><span>  Process: <span style="color:#f99b15">13362</span> <span style="color:#ef6155">ExecStart</span><span style="color:#5bc4bf">=</span>/usr/local/sbin/urbackupclientbackend -d <span style="color:#5bc4bf">(</span><span style="color:#ef6155">code</span><span style="color:#5bc4bf">=</span>exited, <span style="color:#ef6155">status</span><span style="color:#5bc4bf">=</span>0/SUCCESS<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span> Main PID: <span style="color:#f99b15">13364</span> <span style="color:#5bc4bf">(</span>urbackupclientb<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    Tasks: <span style="color:#f99b15">11</span> <span style="color:#5bc4bf">(</span>limit: 4915<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>   CGroup: /system.slice/urbackup.service
</span></span><span style="display:flex;"><span>           └─13364 /usr/local/sbin/urbackupclientbackend -d
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Feb <span style="color:#f99b15">15</span> 17:33:37 ptb-mlm systemd<span style="color:#5bc4bf">[</span>1<span style="color:#5bc4bf">]</span>: Starting Urbackup Backend…
</span></span><span style="display:flex;"><span>Feb <span style="color:#f99b15">15</span> 17:33:37 ptb-mlm systemd<span style="color:#5bc4bf">[</span>1<span style="color:#5bc4bf">]</span>: Started Urbackup Backend.
</span></span></code></pre></div><h2 id="utilisation">Utilisation</h2>
<p>Le binaire du client graphique se nomme <code>urbackupclientgui</code> et nécessite
des droits administrateurs pour le paramétrage de celui-ci :</p>
<ul>
<li>Vérifiez que le binaire &ldquo;gksu&rdquo; soit installé, si ce n&rsquo;est pas le cas, faites-le !</li>
<li>Puis ajoutez votre identifiant utilisateur au groupe sudo : <br>
<code># adduser USERID sudo</code></li>
<li>Déconnectez-vous, et reconnectez-vous à votre session.</li>
<li>Puis, dans votre session, une fois connecté, ajoutez le démarrage du
client Gui, dans les paramètres de &ldquo;Session et démarrage&rdquo; -
<em>qui dépendent de votre bureau graphique</em> ; <br>
le chemin du binaire est : <code>/usr/local/bin/urbackupclientgui</code></li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">L&rsquo;équivalent de ces menus est gérable au-travers de l&rsquo;interface web du serveur
(http://ip_serveur:55414) ; choisissez le menu &ldquo;Réglages&rdquo;, puis le client
à gérer dans la liste déroulante &ldquo;Clients&rdquo;.</div>

<h3 id="menu-do--backups">Menu &ldquo;Do * Backups&rdquo;</h3>
<ul>
<li>Le menu &ldquo;Do full file backup&rdquo; est l&rsquo;option qui vous permet de faire une
<strong>sauvegarde de tous</strong> les fichiers et répertoires choisis…</li>
<li>Le menu &ldquo;Do incremental file backup&rdquo; est l&rsquo;option qui vous permet de
faire une sauvegarde dite incrémentale ; celle qui sauvegarde juste
les différences…</li>
</ul>
<h3 id="menu-settings">Menu &ldquo;Settings&rdquo;</h3>
<ul>
<li>Onglet &ldquo;File Backup&rdquo; :
<ul>
<li>Les champs d&rsquo;intervalle sont là pour définir le nombre de jours pour
les sauvegardes, principalement.</li>
<li>Les champs &ldquo;Exclude from backup&rdquo;, et &ldquo;Include in backup&rdquo; sont ceux
qui vous permettent d&rsquo;inclure ou d&rsquo;exclure des fichiers spécifiques -
à séparer par le symbole &lsquo;;&rsquo;.</li>
</ul>
</li>
<li>Onglet &ldquo;Client&rdquo; :
<ul>
<li>Le champ &ldquo;Client&rdquo; est celui qui vous permettra de nommer la station
à sauvegarder - par défaut, il prend la valeur du <strong>hostname</strong>.</li>
</ul>
</li>
<li>Onglet &ldquo;Internet&rdquo; :
<ul>
<li>Cet onglet n&rsquo;est intéressant que pour ceux qui veulent sauvegarder
au-travers d&rsquo;un Internet… <br>
<em>il serait assurément intéressant d&rsquo;envisager ce flux-là au-travers d&rsquo;un tunnel SSH !</em></li>
</ul>
</li>
</ul>
<h3 id="menu-addremove-backup-paths">Menu &ldquo;Add/Remove backup paths&rdquo;</h3>
<p>Ce menu est celui qui vous permettra d&rsquo;ajouter ou supprimer les répertoires
que vous voulez sauvegarder !</p>
<hr>
<p><em><strong>Enjoy-ID! <br>
Enjoy-IT!</strong></em></p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment installer le client graphique - GUI - d&#39;Urbackup, logiciel de sauvegarde, sous Debian, ou Ubuntu]]></summary>
        <published>2018-02-15T18:21:22+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4098b021-2c06-a4fa-c0fd-4619c3f90392</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/adb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: adb sous OpenBSD (outil de communication avec Android)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="adb" scheme="http://doc.huc.fr.eu.org/fr/tags/adb/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>L&rsquo;usage de l&rsquo;outil <code>adb</code> pour communiquer avec vos périphériques sous Android
<em>(tel que smartphone, tablette, etc…)</em> est possible !</p>
<p><em>Il existe une <a href="http:*cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/dev/usb/usbdevs" rel="external">liste des périphériques</a> connus
pour fonctionner - <strong>vous y trouverez les identifiants vendeurs nécessaires</strong>.</em></p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>adb</strong>.</p>
<ul>
<li>Version testée : <strong>adb-5.1.1.4</strong></li>
<li>OS : <strong>OpenBSD 6.x</strong></li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Veillez à ce que votre périphérique android soit en mode <code>debug developper</code>,
puis activez l&rsquo;option <code>debug USB</code> !</p>
<h2 id="utilisation">Utilisation</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Toutes les commandes liées à l&rsquo;usage d&rsquo;adb s&rsquo;utilisent en mode console !</div>

<h3 id="adb-devices">adb devices</h3>
<p>Pour être sûr que votre périphérique soit reconnu, utilisez la commande
<code>adb devices</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ adb devices
</span></span><span style="display:flex;"><span>List of devices attached
</span></span><span style="display:flex;"><span>0123456789ABCDEF device
</span></span></code></pre></div><h3 id="à-laide-">À l&rsquo;aide !</h3>
<p>Pour obtenir l&rsquo;aide des différentes commandes liées à l&rsquo;outil adb, tapez juste
<code>adb</code> dans votre terminal/console.</p>
<h3 id="copier-les-fichiers">Copier les fichiers</h3>
<h3 id="copier-vers-le-périphérique">Copier vers le périphérique</h3>
<p><code>:$ adb push -p /repertoire_local_machine/fichier /repertoire_peripherique_android</code></p>
<h3 id="copier-depuis-le-périphérique">Copier depuis le périphérique</h3>
<p><code>:$ adb pull -a -p /repertoire_peripherique_android/fichier /repertoire_local_machine</code></p>
<p>L&rsquo;option <code>-a</code> copie les informations telles que le temps, et le mode du fichier.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si le répertoire local de la machine n&rsquo;est pas spécifié, le fichier depuis
android sera copié dans le répertoire d&rsquo;où est exécutée la commande <code>adb</code>.</div>

<h3 id="sauvegarde">Sauvegarde</h3>
<p>La commande principale est : <code>:$ adb backup -f nom_fichier_sauvegarde.ab</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si l&rsquo;option <code>-f</code> n&rsquo;est pas spécifiée, le fichier <code>backup.ab</code> sera créé dans le
répertoire courant où est exécutée la commande de sauvegarde…</div>

<h3 id="sauvegarder_tout">Sauvegarder tout</h3>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -all </code></p>
<p>Cette commande implique la sauvegarde de toutes les applications installées,
dont les applications systèmes.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Cette option intègre l&rsquo;option <code>-system</code> - <em>pas besoin de la spécifier</em> !</div>

<h3 id="sauvegarde_juste_les_applications">Sauvegarde juste les applications</h3>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -apk -obb</code></p>
<p>Cette commande sauvegarde les fichiers apk des applications installées.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><ul>
<li>L&rsquo;option par défaut est <code>-noapk</code> qui signifie que les fichiers apk ne seront 
pas sauvegardés !</li>
<li>L&rsquo;option <code>-obb</code> implique la sauvegarde des fichiers relatifs aux applications 
installées, tels que fichiers de sauvegarde, de config, etc… </li>
<li>par défaut, c&rsquo;est l&rsquo;option <code>-noobb</code> qui est active !</li>
</ul>
</div>

<hr>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab package1 package2 package_n </code></p>
<p>Celle-ci sauvegarde juste les applications dont les noms sont concernés !</p>
<h3 id="sauvegarde_sd_carte">Sauvegarde SD Carte</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Il est bien sûr nécessaire d&rsquo;avoir une SD Carte dans votre appareil</strong>…</div>

<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -shared </code></p>
<p>Sauvegarde le contenu de la SD Carte, ainsi que de tout répertoire de stockage
partagé.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Par défaut, c&rsquo;est l&rsquo;option <code>-noshared</code> qui est active et implique la non
sauvegarde !</div>

<h3 id="sauvegarde_système">Sauvegarde Système</h3>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -system </code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Par défaut, c&rsquo;est l&rsquo;option <code>-system</code> qui est activée, ce qui a pour effet
d&rsquo;inclure les applications systèmes !</div>

<h3 id="sauvegarde_pertinente">Sauvegarde Pertinente</h3>
<p>Le moyen pertinent de sauvegarder tout correctement, sans s&rsquo;occuper du contenu
de la SD Carte, est :</p>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -apk -obb -all</code></p>
<h3 id="sauvegarde_des_partitions">Sauvegarde des partitions</h3>
<p>L&rsquo;outil <code>adb</code> peut servir à sauvegarder indirectement les partitions de votre
périphérique…</p>
<p>Pour cela, il faut télécharger l&rsquo;outil <a href="http://files.androtab.info/rk2818/devel/rkdump_android.zip" rel="external">rkdump</a> !</p>
<p>Puis l&rsquo;installer ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ adb push rkdump /data/
</span></span><span style="display:flex;"><span>:$ adb shell chmod <span style="color:#f99b15">0755</span> /data/rkdump
</span></span></code></pre></div><p>Pour l&rsquo;utiliser l&rsquo;outil rkdump, veuillez lire son <a href="http://androtab.info/rockchip/devel/rkutils/" rel="external">tutoriel</a>…</p>
<h3 id="restauration">Restauration</h3>
<p><code>:$ adb restore nom_fichier_sauvegarde.ab </code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Attention : Tout ce qui concerne le contenu du fichier de sauvegarde sera
restauré !</strong></div>

<h2 id="erreurs">Erreurs</h2>
<h3 id="adb_devices_rien_nest_affiché">&lsquo;adb devices&rsquo; : rien n&rsquo;est affiché</h3>
<p>Il peut être intéressant d&rsquo;effectuer la manipulation suivante :</p>
<ul>
<li>Créer le fichier <code>~/.android/adb_usb.ini</code>, et écrivez dedans <code>0x</code> suivi de 
votre idVendor</li>
</ul>
<p>Quoiqu&rsquo;il en soit, <strong>redémarrer le serveur adb</strong> : <code>$ adb kill-server</code></p>
<p>Puis relancez la commande <code>adb devices</code>.</p>
<h3 id="adb_devices_offline">&lsquo;adb devices&rsquo; : offline</h3>
<p>Lorsque je tape <code>adb devices</code>, le périphérique est reconnu mais affiché <code>offline</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ adb devices
</span></span><span style="display:flex;"><span>List of devices attached
</span></span><span style="display:flex;"><span>0123456789ABCDEF offline
</span></span></code></pre></div><p>Il vous faudra alors :</p>
<ul>
<li>désactivez l&rsquo;option <code>Débogage USB</code>…</li>
<li>déconnectez/reconnectez votre tablette à l&rsquo;ordinateur, en 
débranchant/rebranchant le câble USB.</li>
<li>activez à nouveau l&rsquo;option <code>Débogage USB</code></li>
</ul>
<p>À ce moment-là, essayez à nouveau la commande <code>adb devices</code> ; vous devriez voir
apparaître votre périphérique… correctement !</p>
<h3 id="adb_devices_no_permissions">&lsquo;adb devices&rsquo; : ???????????? no permissions</h3>
<p>Lorsque je tape <code>adb devices</code>, le périphérique n&rsquo;est pas reconnu et il est
affiché <code>???????????? no permissions</code>.</p>
<p><strong>Il vous faut tuer le serveur, le redémarrer avec des droits administrateur
ensuite le périphérique apparaîtra !</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ adb kill-server
</span></span><span style="display:flex;"><span>:$ adb start-server
</span></span><span style="display:flex;"><span>   daemon not running. starting it now on port <span style="color:#f99b15">5037</span>
</span></span><span style="display:flex;"><span>   daemon started successfully
</span></span><span style="display:flex;"><span>:$ adb devices
</span></span><span style="display:flex;"><span>List of devices attached
</span></span><span style="display:flex;"><span>0123456789ABCDEF device
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Comment installer et utiliser l&#39;outil adb - outil pour communiquer avec des périphériques Android - sous OpenBSD]]></summary>
        <published>2017-08-20T21:36:28+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f06eb632-dcec-a677-3a85-cac19d260803</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/redshift/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : Utiliser Redshift pour ajuster automatiquement la température de couleurs</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="redshift" scheme="http://doc.huc.fr.eu.org/fr/tags/redshift/" />
        <category term="température" scheme="http://doc.huc.fr.eu.org/fr/tags/temp%C3%A9rature/" />
        <category term="couleur" scheme="http://doc.huc.fr.eu.org/fr/tags/couleur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Redshift</strong> est un utilitaire système qui paramètre la température des
couleurs de votre écran selon l&rsquo;heure du jour, et de votre position géographique.
Le but de cet outil est de vous aider à moins fatiguer vos yeux, la nuit,
et à réduire les risques liés au syndrome de retard de phase de sommeil,
lors de votre vision informatique en soirée.</p>
<p>La température de couleur est paramétrée en fonction de la position du soleil.
La température de couleur est réglée différemment selon le jour ou la nuit.</p>
<p>Durant le crépuscule, et au petit matin, la température de couleur varie
doucement de la nuit vers la température de jour en permettant à vos yeux
de s&rsquo;adapter lentement sur une période d&rsquo;une heure environ.</p>
<p>La nuit, la couleur de température devrait être paramétrée pour correspondre
avec celles de vos lampes. C&rsquo;est typiquement une basse température autour de
3000-4000K (par défaut est 3700K) .</p>
<p>Durant la journée, la température de couleur doit correspondre avec celle
de la lumière du jour, de fait entre 5500-6500K (par défaut est de 5500K).
La lumière a une température plus haute par temps nuageux.</p>
<p>La température neutre est de 6500K. Utiliser cette valeur ne change pas
la température de votre écran. Régler sur une valeur plus importante définira
une lumière tirant vers le bleu ; définir une valeur plus bas se traduira
par une lumière plus rouge.</p>
<p>Voici les valeurs par défaut de température : <strong>Jour: 5500K, Nuit: 3700K</strong></p>
<h2 id="installation">Installation</h2>
<p><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le paquet <strong>redshift</strong> .</p>
<h2 id="synopsis">Synopsis</h2>
<p>redshift [-l LAT:LON | -l PROVIDER:OPTIONS] [-t DAY:NIGHT] [OPTIONS&hellip;]</p>
<h2 id="configuration">Configuration</h2>
<p>Placez votre fichier de configuration personnelle dans <code>~/.config/redshift.conf</code>.
C&rsquo;est un simple fichier au standard INI.</p>
<p>Voici sa configuration de base :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#815ba4">[redshift]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">temp-day</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">5500</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">temp-night</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">3700</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">gamma</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0.8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">adjustment-method</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">randr</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">location-provider</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">manual</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">[manual]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">lat</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">44.1333</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">lon</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0.35</span>
</span></span></code></pre></div><h3 id="définir-les-températures">Définir les températures</h3>
<h4 id="température-jour">Température jour</h4>
<p>L&rsquo;option <code>temp-day</code> doit être un entier allant de 6500 à 5500.</p>
<h4 id="température-nuit">Température nuit</h4>
<p>L&rsquo;option <code>temp-night</code> doit être un entier allant de 4000 à 3000.</p>
<h4 id="manuellement">Manuellement</h4>
<p>Vous pouvez définir manuellement une température en utilisant <code>redshift</code>,
tel que : <br>
<code>:$ redshift -O TEMP</code> <br>
où <code>TEMP</code> est un entier, à moduler selon la température de période jour
ou nuit désirée. <em>(cf ci-dessous pour les températures de jour et de nuit)</em>.</p>
<p>Les températures de jour et de nuit peuvent aussi être gérées manuellement,
par l&rsquo;usage de <code>redshift</code>, tel que : <br>
<code>:$ redshift -t JOUR/NUIT</code> <br>
où <code>JOUR</code> correspond à la température de jour, et <code>NUIT</code> respectivement
à celle de nuit.</p>
<h3 id="définir-le-gamma">Définir le gamma</h3>
<p>Permet d&rsquo;ajuster le mode gamma, soit de manière globale pour les deux périodes
de jour et de nuit, soit spécifique à l&rsquo;une ou l&rsquo;autre. Ce sont des valeurs
de type RGB qui sont utilisées, tel que <code>R:G:B</code>.</p>
<h4 id="gamma-global">Gamma global</h4>
<p>Ajuste le mode gamma pour les deux périodes : <code>gamma = R:G:B</code></p>
<h4 id="gamma-jour">Gamma jour</h4>
<p>Ajuste le mode gamma juste pour la période jour : <code>gamma-day = R:G:B</code></p>
<h4 id="gamma-nuit">Gamma nuit</h4>
<p>Ajuste le mode gamma juste pour la période nuit : <code>gamma-night = R:G:B</code></p>
<h4 id="manuellement-1">Manuellement</h4>
<p>Le mode gamma global peut aussi être géré manuellement, en utilisant <code>redshift</code>,
tel que :  <br>
<code>:$ redshift -g R:G:B</code> <br>
où <code>R:G:B</code> sont bel et bien les valeurs de couleurs en mode RGB.</p>
<h3 id="définir-la-méthode-dajustement">Définir la méthode d&rsquo;ajustement</h3>
<p>C&rsquo;est le méthode utilisée pour régler la température des couleurs.
La plus commune semble être <code>randr</code>.</p>
<p>Ajustez l&rsquo;option <code>adjustment-method = nom</code>.</p>
<p>Pour connaître le nom des différentes méthodes possibles, utilisez l&rsquo;outil
<code>redshift</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ redshift -m list
</span></span><span style="display:flex;"><span>Méthodes d<span style="color:#48b685">&#39;ajustement disponibles :
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  drm
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  randr
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  vidmode
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">  dummy
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Spécifiez les options séparées par des deux-points en tant que « -m MÉTHODE:OPTIONS ».
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">Essayez « -m MÉTHODE:help » pour obtenir de l&#39;</span>aide.
</span></span></code></pre></div><h3 id="définir-la-latitudelongitude">Définir la latitude/longitude</h3>
<p>Il y a deux moyens de définir vos coordonnées latitude et longitude,
toutes deux gérées par l&rsquo;option <code>location-provider</code>.</p>
<p>Pour connaître les différents fournisseurs de location supportés par
<code>redshift</code>, utilisez-le tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ redshift -l list
</span></span><span style="display:flex;"><span>Fournisseurs de localisation disponibles :
</span></span><span style="display:flex;"><span>  geoclue2
</span></span><span style="display:flex;"><span>  manual
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Spécifiez les options séparées par des deux-points en tant que « -l FOURNISSEUR:OPTIONS ».
</span></span><span style="display:flex;"><span>Essayez « -l FOURNISSEUR:help » pour obtenir de l<span style="color:#ef6155">&#39;</span>aide.
</span></span></code></pre></div><h4 id="automatiquement">Automatiquement</h4>
<p>Le fournisseur <strong>geoclue</strong> est un mode de mise-à-jour automatique de vos coordonnées.</p>
<p>Vous pouvez utiliser le fournisseur geoclue, tel que, par exemple : <br>
<code>:$ redshift -l geoclue2 -t 5500:3700 -b 1.0:0.8</code></p>
<p>Dans votre fichier de configuration, changez la valeur de <code>location-provider</code>
par <code>geoclue2</code>.</p>
<h4 id="manuellement-2">Manuellement</h4>
<p>Pour connaître la latitude, longitude de votre ville, faites une recherche
par le biais d&rsquo;un moteur de recherche, en tapant <code>latitude longitude ville pays</code>…</p>
<p>Dans votre fichier de configuration, changez la valeur de <code>location-provider</code>
par <code>manual</code>. <em>C&rsquo;est le mode par défaut</em>.</p>
<p>Puis dans la section <code>[manual]</code>, définissez les valeurs <code>lat</code> et <code>lon</code>
par les valeurs respectives de latitude et de longitude.</p>
<h3 id="définir-la-transition">Définir la transition</h3>
<p>Il est possible d&rsquo;activer un effet de transition lors de la bascule entre
les deux périodes de jour et de nuit. C&rsquo;est l&rsquo;option <code>transition</code> qui
le gère et doit être un entier de type binaire, strictement, soit <code>0</code>, soit <code>1</code>.</p>
<h3 id="définir-la-luminosité">Définir la luminosité</h3>
<p>Il est possible de gérer la luminosité de l&rsquo;écran, soit pour la période jour,
soit pour la période nuit. Ce sont des valeurs strictement décimales à
utiliser qui vont de <code>0.1</code> à <code>1.0</code>.</p>
<h4 id="luminosité-jour">Luminosité jour</h4>
<p>Ajuste la luminosité de l&rsquo;écran pour la journée :  <code>brightness-day = value</code></p>
<h4 id="luminosité-nuit">Luminosité nuit</h4>
<p>Ajuste la luminosité de l&rsquo;écran pour la nuit : <code>brightness-night = value</code></p>
<h3 id="définir-le-point-délévation-solaire">Définir le point d&rsquo;élévation solaire</h3>
<p>Le point d&rsquo;élévation solaire définit le point de transition entre les deux
périodes de jour et de nuit.</p>
<p>Le point d&rsquo;élévation solaire se définit soit pour le jour, soit pour la nuit.
C&rsquo;est une valeur décimale à utiliser.</p>
<h4 id="élévation-jour">Élévation jour</h4>
<p>Ajuste le point d&rsquo;élévation solaire pour le jour : <code>elevation-high = decimal</code></p>
<h4 id="élévation-nuit">Élévation nuit</h4>
<p>Ajuste le point d&rsquo;élévation solaire pour la nuit : <code>elevation-low = decimal</code></p>
<h2 id="manpage">Manpage</h2>
<p>Pour les différentes options de configuration, veuillez lire la page de
manuel de <code>redshift(1)</code>, accessible seulement sur votre système : <br>
<code>man redshift</code></p>
<p>Voici une copie écran minimaliste de la version disponible dans OpenBSD 6.1 :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>OPTIONS
</span></span><span style="display:flex;"><span>       -h     Display this help message
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -v     Verbose output
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -V     Show program version
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -b DAY:NIGHT
</span></span><span style="display:flex;"><span>              Screen brightness to apply <span style="color:#5bc4bf">(</span>between 0.1 and 1.0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -c FILE
</span></span><span style="display:flex;"><span>              Load settings from specified configuration file
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -g R:G:B
</span></span><span style="display:flex;"><span>              Additional gamma correction to apply
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -l LAT:LON
</span></span><span style="display:flex;"><span>              Your current location, in degrees, given as floating point
</span></span><span style="display:flex;"><span>              numbers, towards north and east, with negative numbers
</span></span><span style="display:flex;"><span>              representing south and west, respectively.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -l PROVIDER<span style="color:#5bc4bf">[</span>:OPTIONS<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>              Select provider <span style="color:#815ba4">for</span> automatic location updates <span style="color:#5bc4bf">(</span>Use <span style="color:#48b685">`</span>-l list<span style="color:#48b685">&#39; to
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">              see available providers)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">       -m METHOD[:OPTIONS]
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">              Method to use to set color temperature (Use `-m list&#39;</span> to see
</span></span><span style="display:flex;"><span>              available methods<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -o     One shot mode <span style="color:#5bc4bf">(</span><span style="color:#815ba4">do</span> not continuously adjust color temperature<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -O TEMP
</span></span><span style="display:flex;"><span>              One shot manual mode <span style="color:#5bc4bf">(</span>set color temperature<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -p     Print mode <span style="color:#5bc4bf">(</span>only print parameters and exit<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -x     Reset mode <span style="color:#5bc4bf">(</span>remove adjustment from screen<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -r     Disable temperature transitions
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       -t DAY:NIGHT
</span></span><span style="display:flex;"><span>              Color temperature to set at daytime/night
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       The neutral temperature is 6500K. Using this value will not change the
</span></span><span style="display:flex;"><span>       color temperature of the display. Setting the color temperature to a
</span></span><span style="display:flex;"><span>       value higher than this results in more blue light, and setting a lower
</span></span><span style="display:flex;"><span>       value will result in more red light.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>       Default temperature values:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>              Daytime: 5500K, night: 3700K
</span></span></code></pre></div><h2 id="utilisation">Utilisation</h2>
<h3 id="en-mode-console">En mode console</h3>
<p>Il est possible de l&rsquo;exécuter directement en mode console, tel que :</p>
<p><code>:$ redshift -l 44.1333:0.35 -t 5700:3600 -g 0.8 -m randr -v &amp;</code></p>
<h3 id="exécution-en-mode-graphique">Exécution en mode graphique</h3>
<p>Allez dans le menu &ldquo;Applications&rdquo; &gt; &ldquo;Accessoires&rdquo;.</p>
<h3 id="lancement-automatique">Lancement automatique</h3>
<p>Éxecutez le binaire <code>redshit-gtk</code> :</p>
<p><code>:$ /usr/local/bin/redshift-gtk</code></p>
<p>L&rsquo;icône s&rsquo;affichera dans le systray. Faites un clic droit et choisissez
de cocher &ldquo;Lancement automatique&rdquo;.</p>
<p>Sinon, modifiez les paramètres systèmes, tel que &ldquo;Session et démarrage&rdquo;
pour XFCE, puis l&rsquo;onglet &ldquo;Démarrage automatique d&rsquo;application&rdquo;, pour ajouter
une application.</p>
<p>Dans le champ nommé &ldquo;commande&rdquo;, écrivez <code>redshift-gtk</code> ou le chemin absolu
vers le binaire <code>/usr/local/bin/redshift-gtk</code>.</p>
<p>Quand vous serez dans votre session graphique, vous aurez le logiciel qui
fonctionnera en tâche de fond, et l&rsquo;icône &ldquo;redshift&rdquo; dans le systray.</p>
<h2 id="bogues-connus">Bogues connus</h2>
<p>Redshift n&rsquo;affecte pas la température de couleur si votre pilote graphique
est configuré pour utiliser matériellement votre curseur.</p>
<p>Quelques pilotes logiciels graphiques ont l&rsquo;option pour désactiver matériellement
le curseur dans le fichier xorg.conf.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le logiciel Redshift sous OpenBSD - filtre lumineux selon horaire de journée ; ajustement automatique de la température de couleurs de l&#39;écran ; rien que pour soulager vos yeux…]]></summary>
        <published>2017-08-20T21:50:17+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:c7d2538b-1c7b-633d-fc84-914eba2b8ff5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/rfc4716/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : au format RFC 4716</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="RFC" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc/" />
        <category term="RFC4716" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc4716/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>SSH a son propre format de génération de ses clés. Or, dans certains
contextes, tel que le projet <a href="http://openmediavault.org" rel="external">OMV</a>,
il est nécessaire de fournir votre clé publique au format RFC 4716 !</p>
<p>La norme <a href="https://www.rfc-editor.org/info/rfc4716" title="RFC Editor : Information à-propos de la RFC 4716">RFC 4716</a>
 est une simple présentation de la clé privée ou
publique dans un format texte, dit ASCII, ni plus, ni moins ;-)</p>
<h2 id="génération">Génération</h2>
<p>Comme pour 
<a class="inside" href="/fr/sec/ssh/configuration-securisee/" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">créer sa clé</a>
,
on utilise l&rsquo;outil <code>ssh-keygen</code>, de telle manière :</p>
<p>⇒ Pour une clé ed25519 : <br>
<code>$ ssh-keygen -e -f ~/.ssh/id_ed25519 &gt; id_ed25519_rfc4716.pub</code></p>
<p>⇒ Idem pour une clé RSA : <br>
<code>$ ssh-keygen -e -f /home/zou/.ssh/id_rsa &gt; id_rsa_rfc4716.pub</code></p>
<p>Il ne vous reste plus qu&rsquo;à copier-coller le contenu du fichier dans
l&rsquo;interface ou sur le serveur où ce format vous est demandé.</p>
<hr>
<p>Bien-sûr il est possible de la générer directement dans votre terminal ;
pour cela, n&rsquo;utilisez pas la redirection de sortie :</p>
<p><code>ssh-keygen -e -f ~/.ssh/id_ed25519</code></p>
<h2 id="documentation">Documentation</h2>

<h3 id="rfc-4716">RFC 4716</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4716" title="RFC 4716 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4716" title="RFC 4716 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4716.txt" title="RFC 4716 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4716.html" title="RFC 4716 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4716.txt.pdf" title="RFC 4716 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4716.txt" title="RFC 4716 : au format Text">TXT</a>
	</dd>
</dl>

<hr>
]]></content>
        <summary type="html"><![CDATA[Comment transformer votre clé SSH au format spécifié par la RFC 4716]]></summary>
        <published>2017-08-17T17:37:53+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1d953325-a264-861c-1f33-553ece5b3cb0</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/x-content-type-options/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: X-Content-Type-Options (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="X Options" scheme="http://doc.huc.fr.eu.org/fr/tags/x-options/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>X-Content-Type-Options</strong> est une technique de base qui demande aux clients web
de ne pas (télé)charger des ressources, tels que des scripts ou des feuilles
de styles à moins que le serveur n&rsquo;indique correctement le type
<abbr title="Multipurpose Internet Mail Extensions">MIME</abbr>
.<br>
Sans cette entête, les clients web pourraient télécharger n&rsquo;importe quoi,
et ainsi être victimes d&rsquo;attaques.</p>
<p><strong>X-Content-Type-Options</strong> est une entête <abbr title="HyperText Transfert Protocol">HTTP</abbr>
,
dont la mise-en-place est extrêmement aisé, mais le bénéfice est faible !</p>
<p>Il n&rsquo;existe qu&rsquo;une seule option possible : <code>nosniff</code></p>
<p>Elle fait partie des entêtes de base à générer pour protéger son site
web, au même titre que l&rsquo;usage de 
<a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS</a>
, et
des autres entêtes X-*-Options, telles que

<a class="inside" href="/fr/web/http/x-frame-options/" title="Lien interne vers l&#39;article : 'X-Frame-Options (header)'">X-Frame-Options</a>
, ou

<a class="inside" href="/fr/web/http/x-xss-protections/" title="Lien interne vers l&#39;article : ''">X-XSS-Protections</a>
…</p>
<h2 id="exemples">Exemples</h2>
<p><code>X-Content-Type-Options: nosniff</code></p>
<h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">X-Content-Type-Options</span> <span style="color:#48b685">&#34;nosniff&#34;</span> <span style="color:#48b685">always</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce sera
son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code>match response header set &#34;X-Content-Type-Options&#34; value &#34;nosniff&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Cross-site_scripting" title="Article Wikipédia : Cross-site_scripting">Cross-site_scripting <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur l&#39;entête HTTP nommée X-Content-Type-Options]]></summary>
        <published>2017-08-16T16:13:25+01:00</published>
        <updated>2018-10-12T02:48:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9b9254c9-d10d-a826-f17e-c10ff351c1a3</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/x-frame-options/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: X-Frame-Options (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="X Options" scheme="http://doc.huc.fr.eu.org/fr/tags/x-options/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>X-Frame-Options</strong> est une entête HTTP qui permet de contrôler
comment les sites internet externes peuvent &ldquo;encapsuler&rdquo; le
vôtre.</p>
<p>L&rsquo;usage de cette entête est recommandé, d&rsquo;autant qu&rsquo;elle est simple à
gérer et son bénéfice de sécurité est important.</p>
<p>Cette entête remplace l&rsquo;historique entête <code>Frame-Options</code>, et est
elle-même remplacée par la directive <code>frame-ancestors</code> de l&rsquo;entête

<a class="inside" href="/fr/web/http/csp/" title="Lien interne vers l&#39;article : 'CSP : Content Security Policy (header)'">CSP</a>
 !</p>
<p>Elle fait partie des entêtes de base à générer pour protéger son site
web, au même titre que l&rsquo;usage de 
<a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS</a>
, et
des autres entêtes X-*-Options, telles que

<a class="inside" href="/fr/web/http/x-content-type-options/" title="Lien interne vers l&#39;article : 'X-Content-Type-Options (header)'">X-Content-Type</a>
,

<a class="inside" href="/fr/web/http/x-xss-protections/" title="Lien interne vers l&#39;article : ''">X-XSS-Protections</a>
,…</p>
<h3 id="options">Options</h3>
<p>3 options sont permises :</p>
<ul>
<li><code>DENY</code> : interdit aux autres de mettre votre site dans une iframe. C&rsquo;est
l&rsquo;<span class="red">option recommandée</span>
 !</li>
<li><code>SAMEORIGIN</code> : permet d&rsquo;être mis dans une frame, à-partir de votre propre site.</li>
<li><code>ALLOW-FROM uri</code> : Cette option est <span class="red">dépréciée</span>
 -
il est clairement recommandée de ne plus l&rsquo;utiliser au profit de la directive
<code>frame-ancestors</code> gérée par l&rsquo;entête 
<a class="inside" href="/fr/web/http/csp/" title="Lien interne vers l&#39;article : 'CSP : Content Security Policy (header)'">CSP</a>
.</li>
</ul>
<h2 id="exemples">Exemples</h2>
<p><code>X-Frame-Options: DENY</code></p>
<h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">X-Frame-Options</span> <span style="color:#48b685">&#34;DENY&#34;</span> <span style="color:#48b685">always</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce sera
son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code>match response header set &#34;X-Frame-Options&#34; value &#34;DENY&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li>Différentes techniques de protections : <a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet" rel="external">https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=X-Frame-Options" rel="external">http://caniuse.com/#search=X-Frame-Options</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur l&#39;entête HTTP nommée X-Frame-Options]]></summary>
        <published>2017-08-16T13:39:25+01:00</published>
        <updated>2018-10-12T02:49:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:784efb61-22bc-beb9-b1af-e01738bce9f1</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/x-xss-protection/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: X-XSS-Protection (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="X Options" scheme="http://doc.huc.fr.eu.org/fr/tags/x-options/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>X-XSS-Protection</strong> est une technique de protection dont le but
est de stopper le (télé)chargement de pages lorsque certaines
attaques sont détectées.</p>
<p>C&rsquo;est une entête HTTP dont le bénéfice est minimale, et aisée à mettre
en place… et dont l&rsquo;impact n&rsquo;est pas négligeable.</p>
<p>Il n&rsquo;existe qu&rsquo;une seule option : <code>1; mode=block</code></p>
<p>Elle fait partie des entêtes de base à générer pour protéger son site
web, au même titre que l&rsquo;usage de 
<a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS</a>
, et
des autres entêtes X-*-Options, telles que

<a class="inside" href="/fr/web/http/x-content-type-options/" title="Lien interne vers l&#39;article : 'X-Content-Type-Options (header)'">X-Content-Type-Options</a>
,

<a class="inside" href="/fr/web/http/x-frame-options/" title="Lien interne vers l&#39;article : 'X-Frame-Options (header)'">X-Frame-Options</a>
…</p>
<h2 id="exemples">Exemples</h2>
<p><code>X-XSS-Protection: 1; mode=block</code></p>
<h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">X-Xss-Protection</span> <span style="color:#48b685">&#34;1</span>; <span style="color:#815ba4">mode=block&#34;</span> <span style="color:#48b685">always</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce sera
son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code>match response header set &#34;X-Xss-Protection&#34; value &#34;1; mode=block&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Cross-site_scripting" title="Article Wikipédia : Cross-site_scripting">Cross-site_scripting <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur l&#39;entête HTTP nommée X-XSS-Protection]]></summary>
        <published>2017-08-16T13:39:25+01:00</published>
        <updated>2018-10-12T02:50:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b2890477-ab98-92c9-1372-3b1d2e8e6dcd</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/sri/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SRI : Subresource Integrity</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="SRI" scheme="http://doc.huc.fr.eu.org/fr/tags/sri/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>SRI</strong> est une norme du <abbr title="World Wide Web Consortium">W3C</abbr>
 pour
protéger des attaques par modification des ressources proposées par
votre site internet, ou de celles que vous ajoutez, fournies par d&rsquo;autres. <br>
Dans l&rsquo;immédiat, elle ne s&rsquo;utilise que pour les scripts <abbr title="JavaScript">JS</abbr>

et les feuilles de styles. Si la somme de contrôle relative à la ressource
attendue ne correspond pas à celle déclarée, alors la ressource n&rsquo;est pas
(télé)chargée par le client web.</p>
<p>Le bénéfice de cette technique est réelle, mais elle peut être un peu complexe
à mettre en place.</p>
<p>Il est possible de l&rsquo;utiliser conjointement avec la directive
<code>require-sri-for</code> de l&rsquo;entête 
<a class="inside" href="/fr/web/http/csp/" title="Lien interne vers l&#39;article : 'CSP : Content Security Policy (header)'">CSP</a>
.</p>
<h2 id="options">Options</h2>
<ul>
<li><code>integrity</code> : la somme de contrôle, encodée en base64, précédée de la fonction
de hash utilisée. Seuls les algorithmes <code>sha256</code>, <code>sha384</code> -
<span class="IMP">recommandation minimale</span> - , et <code>sha512</code> sont
supportés. Il est possible de spécifier plusieurs niveaux de hash, dans ce
cas, ce sera le hash le plus fort qui sera consulté en priorité ; s&rsquo;il
n&rsquo;est pas supporté, ce sera celui qui le précéde.</li>
<li><code>crossorigin</code> : informe le client web que la ressource partagée l&rsquo;est de
manière anonyme, sans aucun cookie. Une seule option : <code>anonymous</code>.</li>
</ul>
<h2 id="exemples">Exemples</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">link</span> <span style="color:#06b6ef">rel</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;stylesheet&#34;</span> <span style="color:#06b6ef">href</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css&#34;</span> <span style="color:#06b6ef">integrity</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u&#34;</span> <span style="color:#06b6ef">crossorigin</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;anonymous&#34;</span>&gt;
</span></span><span style="display:flex;"><span>(…)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">script</span> <span style="color:#06b6ef">type</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;text/javascript&#34;</span> <span style="color:#06b6ef">src</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js&#34;</span> <span style="color:#06b6ef">integrity</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=&#34;</span> <span style="color:#06b6ef">crossorigin</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;anonymous&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#5bc4bf">script</span>&gt;
</span></span></code></pre></div><p>Bien-sûr, il est possible de faire de même - c&rsquo;est fortement encouragé</p>
<ul>
<li>avec vos propres ressources…</li>
</ul>
<h2 id="code">Code</h2>
<p>Ci-dessous, retrouvez le code de génération shell :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cat <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">file</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> | openssl dgst -<span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">algo</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -binary | openssl enc -base64 -A
</span></span></code></pre></div><h2 id="documentations">Documentations</h2>
<ul>
<li>Générateur de hash pour SRI : <a href="https://www.srihash.org/" rel="external">https://www.srihash.org/</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=sri" rel="external">http://caniuse.com/#search=sri</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explication sur l&#39;entête HTTP nommée SRI : Subresource Integrity]]></summary>
        <published>2017-08-16T13:36:25+01:00</published>
        <updated>2018-10-12T02:47:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:35e261b1-d79e-21fa-44f6-fc5078c93720</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/referrer/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: HTTP : Referrer (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="Referrer" scheme="http://doc.huc.fr.eu.org/fr/tags/referrer/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p>L&rsquo;entête <abbr title="HyperText Transfer Protocol">HTTP</abbr>
 <strong>Referrer</strong> est une
politique de protection d&rsquo;un site internet, récente, en cours de travail… <br>
Cette politique permet aux sites web un contrôle fin sur l&rsquo;origine d&rsquo;où vient
le client web.<br>
Cela vous permet de limiter l&rsquo;exposition de votre site web, en limitant
voire interdisant les informations que peuvent contenir cette entête.</p>
<p>Cette entête complète la directive &lsquo;referrer&rsquo; de l&rsquo;entête 
<a class="inside" href="/fr/web/http/csp/" title="Lien interne vers l&#39;article : 'CSP : Content Security Policy (header)'">CSP</a>
</p>
<h2 id="options">Options</h2>
<p>4 options sont utiles :</p>
<ul>
<li><code>no-referrer</code> : ne jamais envoyer l&rsquo;entête ; elle aura une valeur à vide. </li>
<li><code>same-origin</code> : envoie l&rsquo;entête mais seulement si le client se connecte sur le même site</li>
<li><code>strict-origin</code> : envoie l&rsquo;entête, en ne contenant que votre URL, tel que : https://mon.domaine.net</li>
<li><code>strict-origin-when-cross-origin</code> :  envoie l&rsquo;entête complète&hellip; votre URL vers un site extérieur.</li>
</ul>
<h2 id="exemples">Exemples</h2>
<p><code>Referrer-Policy: same-origin</code></p>
<h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">Referrer-Policy</span> <span style="color:#48b685">same-origin</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce sera
son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code>match response header set &#34;Referrer-Policy&#34;         value &#34;same-origin&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Referrer-Policy" rel="external">https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Referrer-Policy</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=Referrer" rel="external">http://caniuse.com/#search=Referrer</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur l&#39;entête HTTP nommée Referrer]]></summary>
        <published>2017-08-16T13:35:25+01:00</published>
        <updated>2020-05-17T04:51:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e3a84299-b9de-09d4-a88d-88abe24d2227</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/csp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: CSP : Content Security Policy (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="Header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="CSP" scheme="http://doc.huc.fr.eu.org/fr/tags/csp/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>CSP</strong> est une politique de sécurité relative au contenu que
votre site &ldquo;distribue&rdquo; vers l&rsquo;utilisateur final, quelque soit
son client web. Cette entête <abbr title="HyperText Transfer Protocol">HTTP</abbr>
 permet de contrôler très
finement l&rsquo;accès aux ressources de votre site et des ressources
partagées par d&rsquo;autres à-partir de votre site.</p>
<p>Cette politique de sécurité impose que le développement des codes <abbr title="Cascade StyleSheet">CSS</abbr>
} et
<abbr title="JavaScript">JS</abbr>
 soit propre, c&rsquo;est-à-dire &ldquo;embarqué&rdquo; par les balises <abbr title="HyperText Markup Language">HTML</abbr>

adéquates pour charger du code source correspondant, et non pas
embarqués dans le code source HTML. On parle de <span lang="en">code
inline</span> ; c&rsquo;est cela qu&rsquo;il faut éviter…</p>
<p>Le bénéfice de sécurité est vraiment important, mais regorge de
difficultés conséquentes, car il est vraiment nécessaire de comprendre
les impacts des différentes directives qui vont plus ou moins empêcher
l&rsquo;accès aux ressources !</p>
<p>Il faut aussi assimiler qu&rsquo;avec une seule entête HTTP, il est possible
d&rsquo;avoir un éventail d&rsquo;interactions qui ne sont pas anodines.</p>
<p>Il y a actuellement deux normes :</p>
<ul>
<li><a href="https://www.w3.org/TR/CSP1/" rel="external">CSP</a> <span class="dark-green">1</span>

est normalement supportée par l&rsquo;ensemble des navigateurs connus, sauf Opera Mini</li>
<li><a href="https://www.w3.org/TR/CSP2/" rel="external">CSP</a> <span class="green">2</span>
 est
généralement bien supportée par l&rsquo;ensemble des navigateurs, seul Firefox a
un support partiel, et IE et Opera Mini n&rsquo;ont pas de support du tout !
<span class="red">Si vous avez un problème d&rsquo;affichage, mettez-à-jour</span>
votre client web - <em>sauf pour les deux derniers suscités</em>…</li>
<li>une <a href="https://www.w3.org/TR/CSP3/" rel="external">troisième version</a> est en cours de travail
auprès du W3C. <span class="red">Officiellement, aucun support pour aucun
navigateur web</span> !</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong> : Si le client web utilisé ne comprend pas une des
directives CSP, il feint de l&rsquo;ignorer, ni plus ni moins…
Pour lui, elle n&rsquo;existe pas !</div>

<h2 id="modes">Modes</h2>
<p>Il y a deux modes possibles, et il est vraiment conseillé de commencer
avec le premier, histoire de réaliser les tenants et aboutissants :</p>
<ul>
<li><code>Content-Security-Policy-Report-Only</code> : ce mode est à considérer comme un
mode de test, qui n&rsquo;a pas d&rsquo;impact sur votre site web, mais permet de tester
les différentes directives</li>
<li><code>Content-Security-Policy</code> : est le mode d&rsquo;application des directives</li>
</ul>
<h2 id="directives">Directives</h2>
<p>Il a vraiment beaucoup de directives, d&rsquo;autant que selon la version de
la politique CSP, certaines sont déclarées obsolètes…</p>
<p>La première directive à mettre-en-place est la directive par défaut :</p>
<ul>
<li><code>default-src</code> : est la directive qui définit par défaut le comportement de
l&rsquo;entête CSP. - norme <span class="dark-green">CSP 1</span>
 - <br>
Attention, <span class="IMP">seules certaines directives sont assujetties</span>
à cette directive par défaut : <code>child-src</code>, <code>connect-src</code>, <code>font-src</code>,
<code>img-src</code>, <code>manifest-src</code>, <code>media-src</code>, <code>object-src</code>, <code>script-src</code>,
<code>style-src</code> et <code>worker-src</code> !</li>
</ul>
<hr>
<p>Voici les autres directives qui peuvent être mises-en-place :</p>
<ul>
<li><code>base-uri</code> : définit l&rsquo;URI que le client web utilisera comme base de la page
web affichée - norme <span class="green">CSP2</span>
 -</li>
<li><code>block-all-mixed-content</code> : empêche que le client web (télé)charge du contenu
sur le protocole HTTP alors que la page est consultée en mode HTTPS</li>
<li><code>child-src</code> : définit les sources valides relatives aux contenus autorisés -
norme <span class="green">CSP2</span>
 -</li>
<li><code>connect-src</code> : définit quelles sources sont valides pour les connexions de
type XMLHttpRequest, WebSocket, et assimilées. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>disown-opener;</code> : assure qu&rsquo;une ressource ne puisse être ouverte lors de sa
consultation - norme <span class="dark-red">CSP3</span>
 -</li>
<li><code>font-src</code> : directive ayant un impact sur les polices à afficher. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>form-action</code> : définit l&rsquo;interaction avec l&rsquo;élément HTML form. -
norme <span class="green">CSP2</span>
 -</li>
<li><code>frame-ancestor</code> : directive pour les ressources partagées par les frames
embarquées - norme <span class="green">CSP2</span>
 -
<em>c&rsquo;est l&rsquo;équivalent de l&rsquo;entête <a href="web:http:x-frame-options" rel="external">X-Frame-Options</a></em>…</li>
<li><code>frame-src</code> : directive pour les ressources partagées par les frames embarquées. -
norme <span class="dark-green">CSP 1</span>
 -
<span class="orange">dépréciée</span>
 en <span class="green">CSP2</span>
 - <em>réintroduite dans <span class="dark-red">CSP 3</span>
</em></li>
<li><code>img-src</code> : directive ayant un impact sur les images à charger. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>manifest-src</code> : définit quel manifeste peut être appliquée à la ressource. -
norme <span class="dark-red">CSP3</span>
 -</li>
<li><code>media-src</code> : directive pour les ressources audio, et vidéo. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>navigate-to</code> : directive pour contrôler les ressources autorisées à la
navigation - norme <span class="dark-red">CSP3</span>
 -</li>
<li><code>object-src</code> : directive pour les ressources qui chargent des plugins, des
applets et autres éléments embed. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>plugin-types</code> : directive qui définit le type des ressources qui peuvent
être chargées. - norme <span class="green">CSP2</span>
 -</li>
<li><code>referrer</code> : directive <em>équivalent à l&rsquo;entête <a href="web:http:referrer" rel="external">Referrer</a></em> -
cette directive a ses propres mots-clés !</li>
<li><code>reflected-xss</code> : directive pour filtrer les attaques de type XSS -
<em>équivalent de l&rsquo;entête <a href="web:http:x-xss-protections" rel="external">X-XSS-Protection</a></em> -
cette directive a ses propres mots-clés !</li>
<li><code>report-to</code> : spécifie un jeton qui définit un groupe de rapports à envoyer. -
norme <span class="dark-red">CSP3</span>
 -</li>
<li><code>report-uri:</code> : directive qui définit l&rsquo;URL où reporter les violations de
sécurité. - norme <span class="dark-green">CSP 1</span>
 -
<em>dépréciée en <span class="dark-red">CSP3</span>
, au profit de
<code>report-to</code></em> -</li>
<li><code>require-sri-for</code> : directive qui oblige l&rsquo;attribut 
<a class="inside" href="/fr/web/http/sri/" title="Lien interne vers l&#39;article : 'SRI : Subresource Integrity'">SRI</a>

pour les scripts et autres styles. - cette directive a ses propres mots-clés !</li>
<li><code>sandbox</code> : directive qui utilise une sandbox HTML pour protéger l&rsquo;exécution
des ressources. - cette directive a ses propres mots-clés ! -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>script-nonce</code> : directive qui autorise l&rsquo;exécution d&rsquo;un script seulement
s&rsquo;il y a correspondance avec l&rsquo;attribut <code>nonce</code>. <em>cf : les explications
liées au mot-clé <code>nonce</code> ci-dessous…</em></li>
<li><code>script-src</code> : directive qui régit les scripts exécutables, tels que JS. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>style-src</code> : directive qui régit les feuilles de styles. -
norme <span class="dark-green">CSP 1</span>
 -</li>
<li><code>upgrade-insecure-requests</code> : oblige toute requête faite en HTTP à basculer
en HTTPS si une page est chargée en HTTPS.</li>
<li><code>worker-src</code> : définit quelles URL peuvent être chargées en tant que Worker,
Sharedworker ou ServiceWorker.</li>
</ul>
<p>Il est très possible, du fait de l&rsquo;évolution de la norme de cette
entête que j&rsquo;ai oublié la présentation de certaines directives…
veuillez vérifier auprès du W3C.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Je ne détaillerai pas plus les
différentes directives… pour cela, veuillez lire les documentations
sur lesquelles j&rsquo;attire votre attention dans la section ad hoc, et les
référentiels W3C.</div>

<h3 id="notes">Notes</h3>
<ul>
<li>Du fait que la directive <code>default-src</code> n&rsquo;a pas d&rsquo;impact sur certaines directives,
telles que <code>frame-ancestor</code>, <code>form-action</code>, si ces dernières ne sont pas
spécifiées, alors l&rsquo;émission de données correspondantes sera envoyée…</li>
<li>La directive <code>block-all-mixed-content</code> est évaluée après la directive
<code>upgrade-insecure-requests</code></li>
<li>La directive <code>child-src</code> remplace la directive <code>frame-src</code>
<ul>
<li>Si la directive <code>child-src</code> n&rsquo;est pas définie, elle est influencée par
<code>default-src</code>- <em>c&rsquo;est le cas de toutes les directives assujetties à
cette dernière</em></li>
<li>Il est préférable de l&rsquo;utiliser pour les scripts &ldquo;dépendants&rdquo; plutôt que
l&rsquo;usage de la directive <code>script-src</code>.</li>
<li>Si les directives <code>frame-src</code>, <code>work-src</code> ne sont pas spécifiées, la
politique <code>child-src</code> s&rsquo;applique.</li>
</ul>
</li>
<li>La directive <code>plugins-type</code> n&rsquo;accepte pas le caractère wildcard <code>*</code> ; il faut
<span class="red">définir un type MIME</span> : <em>e.g : <code>application/pdf</code></em> !</li>
</ul>
<h4 id="recommandations">Recommandations</h4>
<ul>
<li>La première des recommandations est : <span class="red">Il n&rsquo;y a rien de pire
de ne rien faire que</span> de spécifier plusieurs fois la même directive…
seule la première directive est prise-en-compte !</li>
<li>La deuxième est de démarrer avec la déclaration suivante :
<code>default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self';</code> ;
et de voir comment cela réagit ! ;-)</li>
<li>Concernant la directive <code>object-src</code>, préférez l&rsquo;usage du mot-clé <code>none</code>,
sauf à avoir l&rsquo;absolu nécessité d&rsquo;exécuter des scripts Flash, ou Silverlight.</li>
<li>Concernant les directives <code>block-all-mixed-content</code> et <code>upgrade-insecure-requests</code>,
il est recommandé d&rsquo;activer ou l&rsquo;une, ou l&rsquo;autre, mais pas les deux !</li>
<li>Attention à l&rsquo;usage de la déclaration suivante : <code>script-src 'self'</code> qui peut
ne pas être sûre en présence de JSONP.</li>
<li>Idéalement, utiliser la directive <code>report-uri</code> qui postera du contenu JSON
pour relever les violations de sécurité, par vos propres moyens, ou
au-travers d&rsquo;un service fourni par un tiers.</li>
</ul>
<h3 id="mots-clés">Mots-clés</h3>
<p>Aux directives, il est possible d&rsquo;appliquer un ou plusieurs mots-clés :</p>
<ul>
<li><code>*</code> : autorise toutes les ressources. Ce wilcard peut s&rsquo;appliquer aussi dans
l&rsquo;écriture des schemes, des URL et des ports autorisés, tel que :
<code>*://*.domaine.xyz://</code> : <br>
<em>cet exemple signifie l&rsquo;autorisation de toutes les ressources des différents
sous-domaines, quelque soit le protocole utilisé, et sur n&rsquo;importe quel
port de connexion.</em></li>
<li><code>'none'</code> : refuse toutes les ressources - C&rsquo;est la <span class="red">politique
à préférer, en terme de sécurité absolue, sur la directive par défaut</span> !</li>
<li><code>'self'</code> : autorise les ressources du domaine en cours ; ne gèrent pas les
ressources de sous-domaines, s&rsquo;ils existent… il faut les autoriser
explicitement par l&rsquo;ajout de l&rsquo;URL correspondante ! - C&rsquo;est la politique
minimale à appliquer sur la directive par défaut.</li>
<li><code>'strict-dynamic'</code> : autorisera les scripts à charger leurs dépendances sans
avoir à les autoriser spécifiquement -
norme <span class="dark-red">CSP3</span>
 -</li>
<li><code>'unsafe-inline'</code> : permet l&rsquo;usage du code inline CSS ou JS.</li>
<li><code>'unsafe-eval'</code> : permet l&rsquo;évaluation de tout…</li>
<li><code>'unsafe-hashed-attributes'</code> : autorisera les gestionnaires d&rsquo;événements
selon leur hash. - norme <span class="dark-red">CSP3</span>
 -</li>
</ul>
<hr>
<p>Mots-clés relatifs à la gestion des données - dans chaque cas, il est
strictement nécessaire de spécifier une URI :</p>
<ul>
<li><code>blob:</code> : autorise l&rsquo;usage de binaires</li>
<li><code>data:</code> : autorise l&rsquo;usage des données relatives à certaines directives
utilisées, telles que les directives <code>script-src</code>, <code>styles-src</code>,… cela peut
être des images encodées en base64</li>
<li><code>filesystem:</code> : autorise l&rsquo;usage de ressources depuis le système de fichiers.</li>
<li><code>https:</code> : oblige les ressources à être chargées absolument par le biais du
protocole HTTPS.</li>
<li><code>mediastream:</code> : autorise le chargement de streaming de médias audio, vidéo,…</li>
<li><code>wss:</code> : autorise le chargement des websockets !</li>
</ul>
<hr>
<p>Mots-clés relatifs à la directive <em>referrer</em> :</p>
<ul>
<li><code>origin</code> : le client web envoie toujours l&rsquo;origine de l&rsquo;entête vers le même site</li>
<li><code>origin-when-cross-origin</code> : le client web enverra l&rsquo;origine de l&rsquo;entête
uniquement vers le même site même lorsque les origines sont croisées.</li>
<li><code>no-referrer</code> : n&rsquo;envoie pas l&rsquo;entête</li>
<li><code>no-referrer-when-downgrade</code> : n&rsquo;envoie pas l&rsquo;entête quand le client navigue
depuis HTTPS vers HTTP</li>
<li><code>same-origin</code> : envoie l&rsquo;entête si seulement vers le même site</li>
<li><code>unsafe-url</code> :  envoie toujours l&rsquo;entête vers tous.</li>
</ul>
<hr>
<p>Mots-clés relatifs à la directive <em>reflected-xss</em> :</p>
<ul>
<li><code>allow</code> : désactive toute protection contre les attaques XSS.</li>
<li><code>block</code> : bloque le chargement des ressources si une attaque XSS est détectée</li>
<li><code>filter</code> : filtre la charge XSS avant son exécution</li>
</ul>
<hr>
<p>Mots-clés relatifs à la directive <em>require-sri-for</em> :</p>
<ul>
<li><code>script</code> : oblige l&rsquo;attribut integrity pour les scripts</li>
<li><code>style</code> : oblige l&rsquo;attribut integrity pour les styles</li>
<li><code>script, style</code> : oblige l&rsquo;attribut integrity pour les scripts et les styles</li>
</ul>
<hr>
<p>Mots-clés relatifs à la directive <em>sandbox</em> :</p>
<ul>
<li><code>sandbox</code> : active la protection avec toutes les restrictions en place.
Aucune des autres valeurs ne doit être spécifiée afin que toutes les
restrictions soient respectées !</li>
<li><code>allow-forms</code> : permet une page à soumettre un formulaire</li>
<li><code>allow-pointer-lock</code> : évalue la gestion du pointeur de souris.</li>
<li><code>allow-modals</code> : permet les interactions avec le client web.</li>
<li><code>allow-popups</code> : autorise l&rsquo;ouverture de popups</li>
<li><code>allow-same-origin</code> : permet à une page d&rsquo;accéder à du contenu depuis le même site</li>
<li><code>allow-scripts</code> : permet à une page d&rsquo;exécuter ses scripts</li>
<li><code>allow-top-navigation</code> : permet à une page de ???</li>
</ul>
<hr>
<p>Il existe deux mots-clés très spécifiques :</p>
<ul>
<li><code>hash</code> : il permet d&rsquo;autoriser un script, ou un style en particulier selon le
hash définit… le hachage est calculé selon un des trois algorithmes SHA-2
<em>(sha256, sha384 - politique minimale recommandée, sha512)</em>, encodé en base64. <br>
e.g. : <code>style-src 'sha256-HashDigestHere='</code></li>
<li><code>nonce</code> : acronyme de <strong>Number used Once</strong> - <em>Numéro utilisé une seule fois</em> - ;
il permet d&rsquo;autoriser un script inline selon la valeur dynamique aléatoire
autorisé.</li>
</ul>
<p>Il est très possible, du fait de l&rsquo;évolution de la norme de cette entête que
j&rsquo;ai oublié la présentation de certains mots-clés… <br>
veuillez vérifier auprès du W3C.</p>
<h3 id="recommandations-1">Recommandations</h3>
<ul>
<li>Il est <span class="IMP">recommandé d&rsquo;appliquer le mot-clé <code>https:</code> sur la
directive par défaut</span>, tel que : <code>default-src: https:</code>. Cela désactive
le code inline et oblige toute connexion en mode HTTPS seulement.</li>
<li>Il est clairement <span class="IMP">recommandé d&rsquo;éviter l&rsquo;usage</span> du
mot-clé <code>unsafe-inline</code> ! <br>
Malheureusement, parfois certains scripts &ldquo;embarqués&rdquo; ou styles extérieurs
nécessitent des données et autres codes qu&rsquo;il est difficile de gérer finement ;
c&rsquo;est la solution du &ldquo;moins pire&rdquo;</li>
<li>Il est assurément <span class="IMP">recommandé de ne pas utiliser</span> le
mot-clé <code>unsafe-eval</code> !</li>
<li>Attention à l&rsquo;usage du mot-clé <code>data:</code> : par ce biais, il peut remonter des
contenus &ldquo;dérivés&rdquo; inhérents aux directives <code>object-src</code>, <code>script-src</code>,…</li>
<li>L&rsquo;attribut <code>nonce</code> doit <span class="IMP">être unique, re-généré à chaque fois,
et bien entendu doit être non trivial et non devinable</span> !`</li>
</ul>
<h3 id="risques">Risques</h3>
<p>Les risques possibles sont liés à :</p>
<ul>
<li>Des erreurs de configuration, dues à des incompréhensions - d&rsquo;où l&rsquo;intérêt de
tester avant l&rsquo;application ;)</li>
<li>l&rsquo;application de politique trop permissive, tel que l&rsquo;usage des mots-clés <code>unsafe-*</code>…</li>
<li>Utiliser le mot-clé <code>unsafe-inline</code> est l&rsquo;équivalent de ne pas avoir de
politique de sécurité ; quant à utiliser le mot-clé <code>unsafe-eval</code> est
assurément l&rsquo;équivalent d&rsquo;un trou béant dans votre site web où vous permettez à
tout le monde de faire n&rsquo;importe quoi… &lt;= vous, voilà, prévenus !!! <br>
oui, j&rsquo;exagère peut-être un peu… mais le risque est réel, et sérieux.</li>
</ul>
<h2 id="examples">Examples</h2>
<p><code>Content-Security-Policy: default-src https:</code></p>
<p>Il est possible de la définir par le biais de l&rsquo;élément HTML meta, tel
que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#5bc4bf">meta</span> <span style="color:#06b6ef">http-equiv</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Content-Security-Policy&#34;</span> <span style="color:#06b6ef">content</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;script-src &#39;self&#39;&#34;</span>&gt;
</span></span></code></pre></div><h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">Content-Security-Policy</span> <span style="color:#48b685">&#34;default-src</span> <span style="color:#48b685">&#39;self&#39;</span>;<span style="color:#815ba4">&#34;</span> <span style="color:#48b685">always</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce
sera son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code>match response header set &#34;Content-Security-Policy&#34; value &#34;default-src &#39;self&#39; data: &#39;unsafe-inline&#39;; base-uri \*://domain.tld ; form-action &#39;self&#39;; frame-ancestors &#39;none&#39;; referrer no-referrer; reflected-xss block; sandbox allow-same-origin ; script-src &#39;self&#39; cdnjs.cloudflare.com netdna.bootstrapcdn.com ;&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://scotthelme.co.uk/csp-cheat-sheet/" rel="external">https://scotthelme.co.uk/csp-cheat-sheet/</a></li>
<li><a href="https://content-security-policy.com/" rel="external">https://content-security-policy.com/</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" rel="external">https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP</a></li>
<li><a href="https://www.owasp.org/index.php/Content_Security_Policy" rel="external">https://www.owasp.org/index.php/Content_Security_Policy</a></li>
<li><a href="https://openweb.eu.org/articles/content-security-policy" rel="external">https://openweb.eu.org/articles/content-security-policy</a></li>
</ul>
<h3 id="autres-sites-intéressants">Autres sites intéressants</h3>
<ul>
<li><a href="https://report-uri.io" rel="external">https://report-uri.io</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=csp" rel="external">http://caniuse.com/#search=csp</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur l&#39;entête HTTP  nommée CSP : Content Security Policy]]></summary>
        <published>2017-08-16T13:32:25+01:00</published>
        <updated>2018-10-24T11:43:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e404f366-d026-1132-748b-ef540975ba53</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/http/cors/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: CORS : Cross-origin Resource Sharing (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="Header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="CORS" scheme="http://doc.huc.fr.eu.org/fr/tags/cors/" />
        <content type="html"><![CDATA[<h2 id="définition">Définition</h2>
<p><strong>CORS</strong> est une entête HTTP qui contrôle quels sites, externes
ou non, peuvent accéder au contenu de votre site web, par le
biais de scripts, tel que le propose XMLHttpRequest.</p>
<p>C&rsquo;est une technique très facile à mettre en place et dont le bénéfice
est vraiment important !</p>
<p>L&rsquo;usage du symbole <code>*</code> accepte que n&rsquo;importe quel site puisse se
connecter ; sinon, remplissez une URL !</p>
<p>Elle fait partie des entêtes de base à générer pour protéger son site
web, au même titre que l&rsquo;usage de 
<a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS</a>
, et
des autres entêtes, telles que

<a class="inside" href="/fr/web/http/x-content-type-options/" title="Lien interne vers l&#39;article : 'X-Content-Type-Options (header)'">X-Content-Type-Options</a>
,

<a class="inside" href="/fr/web/http/x-frame-options/" title="Lien interne vers l&#39;article : 'X-Frame-Options (header)'">X-Frame-Options</a>
, ou

<a class="inside" href="/fr/web/http/x-xss-protections/" title="Lien interne vers l&#39;article : ''">X-XSS-Protections</a>
,…</p>
<h2 id="exemples">Exemples</h2>
<p><code>Access-Control-Allow-Origin: *</code></p>
<h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">add_header</span> <span style="color:#48b685">Access-Control-Allow-Origin</span> <span style="color:#48b685">&#34;huc.fr.eu.org&#34;</span> <span style="color:#48b685">always</span>;
</span></span></code></pre></div><h3 id="relayd">relayd</h3>
<p>Et, oui, malheureusement, <a class="tag" href="/fr/tags/httpd">httpd</a>
 ne peut pas gérer les entêtes, ce sera
son binôme 
<a class="man" href="https://man.openbsd.org/relayd.8" title="Page du Manuel OpenBSD pour : relayd">relayd(8)</a>
 que l&rsquo;on utilisera !</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">match response header set &#34;Access-Control-Allow-Origin&#34; value &#34;huc.fr.eu.org&#34;
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/CORS" rel="external">https://developer.mozilla.org/fr/docs/Web/HTTP/CORS</a>
<ul>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials" rel="external">Access-Control-Allow-Credentials</a></li>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Allow-Headers" rel="external">Access-Control-Allow-Headers</a></li>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Allow-Methods" rel="external">Access-Control-Allow-Methods</a></li>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Allow-Origin" rel="external">Access-Control-Allow-Origin</a></li>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Expose-Headers" rel="external">Access-Control-Expose-Headers</a></li>
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Access-Control-Max-Age" rel="external">Access-Control-Max-Age</a></li>
</ul>
</li>
<li>Support actuel de l&rsquo;entête : <a href="http://caniuse.com/#search=cors" rel="external">http://caniuse.com/#search=cors</a></li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explication sur l&#39;entête HTTP nommée CORS : Cross-Origin Resource Sharing]]></summary>
        <published>2017-08-16T13:31:25+01:00</published>
        <updated>2020-05-17T04:44:25+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:dece7777-774a-5289-89ee-f966a86d2079</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/unbound/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : utiliser Unbound</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="DNS" scheme="http://doc.huc.fr.eu.org/fr/tags/dns/" />
        <category term="RFC" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc/" />
        <category term="RFC8499" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc8499/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le but d&rsquo;utiliser Unbound est d&rsquo;avoir localement sur sa station son propre
serveur DNS Cache - selon la <a href="https://www.rfc-editor.org/info/rfc8499" title="RFC Editor : Information à-propos de la RFC 8499">RFC 8499</a>
, un <strong>Résolveur complet avec mémoire</strong>
(en anglais, <em>full-service resolver</em>), c&rsquo;est à dire un client DNS qui
fournit un service de résolution complet, avec mémorisation des enregistrements
DNS récoltés.</p>
<p>Utiliser Unbound avec la gestion sécurisée des informations DNS, par le
biais de la technologie DNSSEC, est un plus indéniable. <br>
<em>(cela évite d&rsquo;avoir à obtenir des informations DNS faussées, par une action
pirate, par une action &ldquo;étatique&rdquo;…)</em>.</p>
<p>Sous OpenBSD, <code>unbound</code> est intégré nativement !</p>
<ul>
<li>Pour activer unbound, tapez : <code># rcctl enable unbound</code></li>
<li>Pour le démarrer : <code># rcctl start unbound</code></li>
<li>Pour l&rsquo;utiliser avec une connexion obtenue via, dhcp, ajoutez dans le
fichier <code>/etc/dhclient.conf</code> : <br>
<code>prepend domain-name-servers 127.0.0.1;</code></li>
</ul>
<h3 id="versions-logicielles">Versions logicielles</h3>
<ul>
<li>OS : OpenBSD 6.0 &amp; supérieure</li>
<li>Unbound : natif, intégré</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>La configuration d&rsquo;unbound ne pose pas de gros problème, en soit, il faut
veiller à l&rsquo;écriture correcte des informations !</p>
<p>Toutes les variables et leur impact sont expliquées dans la documentation
officielle anglaise : <a href="https://unbound.net/documentation/unbound.conf.html" rel="external">https://unbound.net/documentation/unbound.conf.html</a></p>
<p><strong>Voyons quelques détails dits de sécurité à paramétrer absolument dans
votre propre fichier de configuration</strong> : <br>
<code>/var/unbound/etc/unbound.conf</code></p>
<p>Pour tester la configuration de vos fichiers, utilisez la commande
<code>unbound-checkconf</code> !</p>
<p>Quand vous avez terminé votre configuration, pensez à redémarrer le service lié
à unbound.</p>
<h3 id="fichier-roothints">Fichier root.hints</h3>
<p>Le fichier <code>root.hints</code> est une liste des serveurs de noms faisant autorité,
les premiers serveurs DNS, dits <code>roots</code>.</p>
<p>Bien qu&rsquo;OpenBSD semble avoir une liste intégrée, il est intéressant de
récupérer ladite liste tous les 6 mois environ.</p>
<p>Pour le récupèrer : <br>
<code># ftp -o /var/unbound/db/root.hints http://www.internic.net/domain/named.cache</code></p>
<p>Puis, modifiez le fichier de configuration, pour ajouter : <br>
<code>root-hints: &quot;/var/unbound/db/root.hints</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Pensez à créer un fichier cron pour mettre-à-jour régulièrement ce fichier…</div>

<h3 id="gestion-des-réseaux-autorisés">Gestion des réseaux autorisés</h3>
<ul>
<li><code>access-control: 127.0.0.0/8 allow</code> # autorise l&rsquo;interface de bouclage local
sur la couche IPv4</li>
<li><code>access-control: :1 allow</code> # autorise l&rsquo;interface de bouclage local sur la
couche IPv6</li>
<li><code>access-control: 192.168.1.0/24 allow</code> # autorise le réseau local</li>
<li><code>access-control: 0.0.0.0/0 refuse</code> # interdit tout le reste de l&rsquo;Internet !</li>
<li><code>access-control: ::0/0 refuse</code> # interdit tout Internet sur IPv6</li>
</ul>
<p><strong>À moins de savoir quoi modifier, laissez tel quel !</strong></p>
<p>Le segment réseau peut-être de type IPv4 ou IPv6. L&rsquo;action à allouer peut-être :</p>
<ul>
<li><code>allow</code> permet l&rsquo;accès</li>
<li><code>allow_snoop</code> permet l&rsquo;accès, en utilisant une technique de &ldquo;cache snopping&rdquo;,
qui donne le droit d&rsquo;examiner le contenu en cache.</li>
<li><code>deny</code> refuse l&rsquo;accès - <code>option par défaut, si non spécifiée</code></li>
<li><code>deny_non_local</code>,</li>
<li><code>refuse</code> refuse l&rsquo;accès, tout en envoyant un message d&rsquo;erreur adéquat.</li>
<li>ou <code>refuse_non_local</code></li>
</ul>
<p><em>Pour les autres options, ou afin de mieux saisir les subtilités, merci de lire
la <a href="https://calomel.org/unbound_dns.html" rel="external">page officielle anglaise</a> !</em></p>
<h3 id="durcir-et-cacher-certaines-informations">Durcir et cacher certaines informations</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound">harden-algo-downgrade: no
harden-glue: yes

hide-identity: yes
hide-version: yes

private-address: 192.168.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8

use-caps-for-id: no

val-clean-additional: yes
</code></pre><p><strong>Explications</strong></p>
<ul>
<li>
<p><code>harden-algo-downgrade</code> empêche ou non de choisir l’algorithme le plus faible .</p>
<ul>
<li>Si <code>no</code> est choisi, ce sera l&rsquo;algorithme le plus faible qui sera élu…</li>
<li>Si les zones DNS ne sont pas configurées pour fonctionner correctement
avec cette option, cela peut entraîner des échecs de validation ;
dans ce cas, il faut la mettre sur <code>no</code>. <br>
<em>Cette option n&rsquo;est pas reconnue avec la version Jessie, utilisez la version
backports !</em></li>
</ul>
</li>
<li>
<p>Les variables <code>private-address</code> renforcent l&rsquo;aspect privé de ces réseaux.
Cela empêche l&rsquo;inclusion de ces segments réseaux dans les réponses DNS,
et protège de la technique des &ldquo;Relais DNS&rdquo;
<em>(qui utilise, par exemple, un navigateur internet comme relais ou proxy
réseau)</em>.</p>
</li>
<li>
<p>La variable <code>use-caps-for-id</code> est expérimentale et peut créer des bogues,
ou résultats incorrects - <em>ne pas l&rsquo;utiliser à moins d&rsquo;être sûr de ce que
vous faites…</em></p>
</li>
<li>
<p>La variable <code>val-clean-additional</code> assure de nettoyer toutes les données DNS
non sécurisées</p>
</li>
</ul>
<h3 id="optimisation">Optimisation</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound">num-threads: 4

key-cache-slabs: 8
infra-cache-slabs: 8
msg-cache-slabs: 8
rrset-cache-slabs: 8

key-cache-size: 16m
msg-cache-size: 4m
rrset-cache-size: 8m

outgoing-range: 206

qname-minimisation: yes

so-rcvbuf: 1m
so-sndbuf: 1m

so-reuseport: yes
</code></pre><p><strong>Explications</strong></p>
<ul>
<li>La variable <code>num-thread</code> correspond au nombre de cœurs CPU dont dispose
votre station, soit pour 4 CPU ayant chacun deux cœurs, on lui attribuera
le chiffre <code>8</code>. <br>
Une manière d&rsquo;être sûr du nombre de cœurs utilisés dans votre machine
est d&rsquo;utiliser la commande suivante :</li>
</ul>
<pre tabindex="0"><code>:$ sysctl hw.ncpu
hw.ncpu=4
:$ sysctl hw.ncpufound
hw.ncpufound=4
</code></pre><ul>
<li>
<p>Les variables terminant par le mot <code>slabs</code> doivent être paramétrées
au double de la variable <code>num-thread</code>. Ces variables gèrent les conflits
de verrouillage en les diminuant.</p>
</li>
<li>
<p>La gestion des variables <code>*-cache-size</code> est sensible et doit être ainsi
paramétrée : la variable <code>rrset-cache-size</code> doit être le double de la
variable <code>msg-cache-size</code> ; quant à la variable <code>key-cache-size</code>, elle
doit être elle-même le double de la variable <code>rrset</code>.</p>
</li>
<li>
<p>La variable <code>outgoing-range</code> qui gère le nombre de connexions par cœurs
CPU doit être ainsi calculée : <br>
<strong>1024 / nb_coeurs_CPU - 50</strong></p>
</li>
<li>
<p>La variable <code>so-reuseport</code> permet d&rsquo;améliorer significativement les performances
de l&rsquo;usage du protocole UDP. <br>
<span class="red">n'est fonctionnelle que sous Linux !</span>
</p>
</li>
<li>
<p>La variable <code>qname-minimisation</code> a pour propos d&rsquo;améliorer les informations
privées liées à l&rsquo;usage de DNS.</p>
</li>
<li>
<p>Lisez la documentation officielle anglaise pour les options <code>so-rcvbuf</code>,
et <code>so-sndbuf</code> qui doivent être augmentées dans le cas de serveur surchargé.
Autrement, laissez la valeur <code>0</code> par défaut - cela utilise les valeurs
systèmes !</p>
</li>
</ul>
<h3 id="gestion-des-caches">Gestion des caches</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound"># garde en cache les bons résultats
prefetch: yes

cache-min-ttl: 3600
cache-max-ttl: 86400
</code></pre><h3 id="gestion-des-journaux">Gestion des journaux</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound"># gestion logs
logfile: /var/log/unbound/unbound.log
use-syslog: yes
unwanted-reply-threshold: 10000000
val-log-level: 2
verbosity: 1
</code></pre><p><strong>Explications</strong></p>
<ul>
<li>
<p>Si l&rsquo;option <code>unwanted-reply-threshold</code> est définie, le nombre paramétré
total de réponses indésirables est gardé dans chacun des processus.
Ce nombre paramétré atteint déclenche une action défensive de nettoyage
des caches <code>rrset</code> et autres messages, un avertissement est affiché
dans les journaux.
<strong>Il est recommandé de positionner ce nombre à une valeur de 10 Millions</strong> ! <br>
<em>Pour info, l&rsquo;excellente <a href="https://calomel.org/unbound_dns.html" rel="external">documentation de Calomel</a> recommande <strong>10000</strong>.</em></p>
</li>
<li>
<p>L&rsquo;option <code>verbosity</code> est le degré de verbosité des journaux :</p>
<ul>
<li><code>0</code> signifie que seules les erreurs seront affichées ;</li>
<li><code>1</code> que ce sont des informations opérationnelles - <em>valeur par défaut</em> - ;</li>
<li><code>2</code> que celles-ci seront plus détaillées ;</li>
<li><code>3</code> définit les informations par niveau de requêtes et leurs sorties ;</li>
<li><code>4</code> restitue l&rsquo;information du niveau d&rsquo;algorithme utilisé ;</li>
<li><code>5</code>, quant à lui, enregistre l&rsquo;identification des clients en cas d&rsquo;erreurs
de cache.</li>
</ul>
</li>
<li>
<p>Mettre l&rsquo;option <code>val-log-level</code> à <code>2</code> permet d&rsquo;atteindre un niveau d&rsquo;explications
suffisant pour obtenir les raisons des échecs. <br>
<em>très utile à utiliser pour

    <a class="inside" href="/fr/sys/openbsd/unbound-dnssec-dns-over-tls/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS'">unbound en mode DNSSEC</a>

!</em> ;)</p>
</li>
</ul>
<h3 id="gérer-des-statistiques">Gérer des statistiques</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound">statistics-interval: 0
extended-statistics: yes
statistics-cumulative: no
</code></pre><p><strong>Explications</strong></p>
<ul>
<li>L&rsquo;option <code>statistics-cumulative</code> est à paramétrer sur <code>yes</code> -
<em>si vous utilisez un outil d&rsquo;affichage graphique des rapports, tel que Munin…</em></li>
</ul>
<h3 id="bloquer-certains-sites">Bloquer certains sites</h3>
<pre tabindex="0"><code class="language-unbound" data-lang="unbound"># bloque certaines pubs
local-zone: &#34;doubleclick.net&#34; redirect
local-data: &#34;doubleclick.net A 127.0.0.1&#34;
local-zone: &#34;googlesyndication.com&#34; redirect
local-data: &#34;googlesyndication.com A 127.0.0.1&#34;
local-zone: &#34;googleadservices.com&#34; redirect
local-data: &#34;googleadservices.com A 127.0.0.1&#34;
local-zone: &#34;google-analytics.com&#34; redirect
local-data: &#34;google-analytics.com A 127.0.0.1&#34;
local-zone: &#34;ads.youtube.com&#34; redirect
local-data: &#34;ads.youtube.com A 127.0.0.1&#34;
local-zone: &#34;adserver.yahoo.com&#34; redirect
local-data: &#34;adserver.yahoo.com A 127.0.0.1&#34;
local-zone: &#34;ask.com&#34; redirect
local-data: &#34;ask.com A 127.0.0.1&#34;
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pour info, il existe des projets de listes, tels que :</p>
<ul>
<li><strong><a href="https://pgl.yoyo.org/adservers/" rel="external">PGL-Yoyo</a></strong></li>
<li>l&rsquo;excellent <strong><a href="https://www.geoghegan.ca/unbound-adblock.html" rel="external">unbound-badhosts</a></strong></li>
</ul>
<p>Dans le cas d&rsquo;usage de listes, il faut les inclure en utilisant la déclaration : <br>
<code>include: /var/unbound/etc/nom-fichier-liste</code></p>
</div>

<h2 id="documentation">Documentation</h2>
<p>Pour savoir comment :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/openbsd/unbound-dnssec-dns-over-tls/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound en mode DNSSEC &#43; DNS/TLS'">configurer Unbound pour utiliser les protocoles DNSSEC, et DNS/TLS</a>
 !</li>
<li>
<a class="inside" href="/fr/sys/openbsd/unbound-control/" title="Lien interne vers l&#39;article : 'OpenBSD : Unbound control'">contrôler le service unbound</a>
</li>
</ul>
<h3 id="autres-documentations">autres documentations</h3>
<ul>
<li>l&rsquo;excellente <a href="https://framagit.org/BlackLists/BlockZones/raw/master/cron/monthly.local" rel="external">documentation de Calomel</a>.org, <em>en anglais</em></li>
<li><a href="http://www.bortzmeyer.org/search?pattern=unbound" rel="external">celles</a> de Stéphane Bortzmeyer, en français</li>
</ul>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/cron.8" title="Page du Manuel OpenBSD pour : cron">cron(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/unbound.8" title="Page du Manuel OpenBSD pour : unbound">unbound(8)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound.conf.5" title="Page du Manuel OpenBSD pour : unbound.conf">unbound.conf(5)</a>
, 
<a class="man" href="https://man.openbsd.org/unbound-checkconf.8" title="Page du Manuel OpenBSD pour : unbound-checkconf">unbound-checkconf(8)</a>
</li>
</ul>

<h3 id="rfc-8499">RFC 8499</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc8499" title="RFC 8499 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc8499" title="RFC 8499 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc8499.txt" title="RFC 8499 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc8499.html" title="RFC 8499 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc8499.txt.pdf" title="RFC 8499 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc8499.txt" title="RFC 8499 : au format Text">TXT</a>
	</dd>
</dl>

<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le serveur unbound - résolveur DNS cache &#43; DNSSEC - sous OpenBSD]]></summary>
        <published>2017-08-15T18:56:30+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3892c3f8-f624-79fd-4d53-e6b886c21797</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/ssl/hsts/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: HSTS : HTTP Strict Transport Security (header)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSL" scheme="http://doc.huc.fr.eu.org/fr/tags/ssl/" />
        <category term="HSTS" scheme="http://doc.huc.fr.eu.org/fr/tags/hsts/" />
        <category term="HTTPS" scheme="http://doc.huc.fr.eu.org/fr/tags/https/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="RFC" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc/" />
        <category term="RFC6797" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc6797/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Sous ce nom barbare qu&rsquo;est <strong>HSTS</strong> se cache une technique assez simple
à mettre-en-œuvre et au bénéfice intéressant.</p>
<p>Cette technologie demande au client web de se connecter uniquement au
protocole HTTPS, même si le serveur web permet la connexion sur le port
associé au protocole HTTP. <br>
Cette technique transparente pour le client impose que toutes les connexions
se font obligatoirement sur le port associé au protocole HTTPS,
généralement le port 443.</p>
<p>Par contre, cette technique est très restrictive car elle empêche que le
client web puisse contourner le protocole, en gérant finement les erreurs
liées ; la finalité étant d&rsquo;avertir le client des dysfonctionnements possibles.</p>
<p><em>Techniquement, c&rsquo;est une entête HTTP !</em></p>
<p>C&rsquo;est la première entête HTTPS à mettre en place, facile à gérer et nativement
gérée par beaucoup de serveurs web !</p>
<h3 id="options">Options</h3>
<p>Il y a trois options, dont une absolument nécessaire !</p>
<ul>
<li><code>max-age</code> définit la durée dans le temps pendant laquelle le client
web est obligé à être redirigée. Cette durée, en nombre de secondes,
doit être minimale de six mois, et maximale de deux ans. <strong>C&rsquo;est l&rsquo;option
par défaut à implémenter !</strong></li>
<li><code>includeSubDomains</code> : cette directive oblige le client à traiter tous
les sous-domaines relatifs à un nom de domaine à être eux aussi résolu en HTTPS !</li>
<li><code>preload</code> : cette directive permet à votre domaine d&rsquo;être géré par
la <a href="https://hstspreload.org" rel="external">liste de préchargement HSTS</a>, après soumission.
Elle a pour propos d&rsquo;empêcher certaines attaques mais n&rsquo;est vraiment
recommandé que pour les sites dits sensibles. Si vous vous êtes soumis
à ladite liste, il est impératif que l&rsquo;option &lsquo;&lsquo;includeSubDomains&rsquo;&rsquo; soit gérée !</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">L&rsquo;usage de l&rsquo;option <code>includeSubDomains</code> semble vraiment importante à
paramétrer sur votre nom de domaine principal. Celle-ci empêcherait une
<a href="https://scotthelme.co.uk/hsts-polish-dns-hijacking-attack/" rel="external">attaque par détournement de DNS</a>,
qui consiste à faire croire en l&rsquo;usage d&rsquo;un sous-domaine pour capturer
le trafic d&rsquo;un client web et en prendre le contrôle. Du fait du rôle de
cette option, tout sous-domaine &ldquo;déclaré&rdquo; se voit obliger de communiquer
en HTTPS, en vérifiant les certificats, la relation avec le nom de domaine
principal et de sous-domaines et en interrogeant l&rsquo;autorité de contrôle.</div>

<h2 id="exemples">Exemples</h2>
<p><code>Strict-Transport-Security: max-age=63072000</code> :
Ce qui correspond à une période de deux années.</p>
<h3 id="httpd">httpd</h3>
<p>Pour le serveur web d&rsquo;OpenBSD :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">server mon.domaine.net {
    listen on * tls port 443
    # Enable HTTP Strict Transport Security (defaults to 1 year).
    hsts
    (…)
}
</code></pre><h3 id="nginx">nginx</h3>
<p>Pour le serveur nginx :</p>
<p><code>add_header Strict-Transport-Security &quot;max-age=31536000;&quot; always;</code></p>
<h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://man.openbsd.org/httpd.conf#hsts" rel="external">https://man.openbsd.org/httpd.conf#hsts</a></li>
<li>Wikipédia : <a href="https://fr.wikipedia.org/wiki/HTTP_Strict_Transport_Security" rel="external">https://fr.wikipedia.org/wiki/HTTP_Strict_Transport_Security</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=hsts" rel="external">http://caniuse.com/#search=hsts</a></li>
</ul>

<h3 id="rfc-6797">RFC 6797</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc6797" title="RFC 6797 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc6797" title="RFC 6797 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc6797.txt" title="RFC 6797 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc6797.html" title="RFC 6797 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc6797.txt.pdf" title="RFC 6797 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc6797.txt" title="RFC 6797 : au format Text">TXT</a>
	</dd>
</dl>

<hr>
]]></content>
        <summary type="html"><![CDATA[Comprendre l&#39;entête de sécurité HSTS]]></summary>
        <published>2017-08-14T03:09:49+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:184b3c3f-92ad-3d19-7ab6-0d9266a80a76</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/ssl/redirect-http-https/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Redirection HTTP vers HTTPS</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSL" scheme="http://doc.huc.fr.eu.org/fr/tags/ssl/" />
        <category term="HTTP" scheme="http://doc.huc.fr.eu.org/fr/tags/http/" />
        <category term="HTTPS" scheme="http://doc.huc.fr.eu.org/fr/tags/https/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La technique de redirection du trafic <abbr title="HyperText Transfer Protocol">HTTP</abbr>

vers <abbr title="HyperText Transfer Protocol Secure">HTTPS</abbr>
 est généralement
simple à comprendre et à mettre en place : <br>
Quand un client web interroge un site internet sur le port 80, il doit
être redirigé automatiquement vers le port 443 qui distribue le même site,
les mêmes ressources mais de manière chiffrée, par l&rsquo;usage de certificats
SSL au niveau du serveur.</p>
<p><strong>La redirection doit être de type permanente.</strong></p>
<p>Le bénéfice de sécurité est maximale pour un coût de mise-en-place simple et aisé.</p>
<p><em>Cette technique dev(r?)ait être complétée de la technologie <a class="inside" href="/fr/web/ssl/hsts/" title="Lien interne vers l&#39;article : 'HSTS : HTTP Strict Transport Security (header)'">HSTS</a>
</em>
afin de  s&rsquo;assurer que toute nouvelle connexion, au site web, soit directement
transmise sur le port HTTPS.</p>
<h2 id="exemples">Exemples</h2>
<h3 id="apache">Apache</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-Apache" data-lang="Apache"><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;VirtualHost</span> <span style="color:#48b685">*:80</span><span style="color:#5bc4bf">&gt;</span>
</span></span><span style="display:flex;"><span>  ServerName mon.domaine.net
</span></span><span style="display:flex;"><span>  Redirect permanent / https://mon.domaine.net/
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">&lt;/VirtualHost&gt;</span>
</span></span></code></pre></div><h3 id="httpd">httpd</h3>
<p>Pour le serveur web d&rsquo;OpenBSD :</p>
<pre tabindex="0"><code class="language-httpd" data-lang="httpd">server mon.domaine.net {
    listen on * port 80
    block return 301 &#34;https://$SERVER_NAME$REQUEST_URI&#34;
}
</code></pre><h3 id="nginx">nginx</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">server</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">listen</span> <span style="color:#f99b15">80</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#5bc4bf">server_name</span> <span style="color:#48b685">mon.domaine.net</span>
</span></span><span style="display:flex;"><span>  <span style="color:#48b685">return</span> <span style="color:#f99b15">301</span> <span style="color:#48b685">https://</span><span style="color:#ef6155">$server_name$request_uri</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Comment effectuer une redirection du protocole HTTP vers le protocole sécurisé HTTPS]]></summary>
        <published>2017-08-14T02:20:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8a8739c3-6587-ab0f-f929-91a78f3739b0</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/ssl/hpkp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: HPKP : HTTP Public Key Pinning (header) [dépréciée]</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSL" scheme="http://doc.huc.fr.eu.org/fr/tags/ssl/" />
        <category term="HPKP" scheme="http://doc.huc.fr.eu.org/fr/tags/hpkp/" />
        <category term="HTTPS" scheme="http://doc.huc.fr.eu.org/fr/tags/https/" />
        <category term="header" scheme="http://doc.huc.fr.eu.org/fr/tags/header/" />
        <category term="obsolète" scheme="http://doc.huc.fr.eu.org/fr/tags/obsol%C3%A8te/" />
        <category term="RFC" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc/" />
        <category term="RFC7469" scheme="http://doc.huc.fr.eu.org/fr/tags/rfc7469/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Cette fonctionnalité est dépréciée, car difficile à mettre en place,
sans parler des dangereux effets de bords si mal maîtrisée…</p>
<p>au profit de l&rsquo;entête <code>Expect-CT</code> !</p>
</div>

<p>Sous ce nom très barbare, <strong>HPKP</strong> se cache une fonctionnalité de sécurité
qui est censée protéger les sites internet contre le vol de leur identité.
Cette technique protège les certificats SSL par l&rsquo;ajout de clés publiques
d&rsquo;authentification adressées au client web. Si les clés ne correspondent pas,
le client web doit interdire purement et simplement l&rsquo;accès au site internet
en question.</p>
<p>C&rsquo;est une technique très complexe à implémenter car il faut gérer correctement
ces clés, les latences entre les différentes clés, celles utilisées, celles
de sauvegarde. Elle est recommandée uniquement pour les sites dits à haut risque.</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>En savoir plus : <a href="https://developer.mozilla.org/fr/docs/Web/Security/Public_Key_Pinning" rel="external">https://developer.mozilla.org/fr/docs/Web/Security/Public_Key_Pinning</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Public-Key-Pins-Report-Only" rel="external">https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Public-Key-Pins-Report-Only</a></li>
<li>Outils : <a href="https://scotthelme.co.uk/hpkp-toolset/" rel="external">https://scotthelme.co.uk/hpkp-toolset/</a></li>
<li>Support actuel : <a href="http://caniuse.com/#search=hpkp" rel="external">http://caniuse.com/#search=hpkp</a></li>
</ul>

<h3 id="rfc-7469">RFC 7469</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc7469" title="RFC 7469 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc7469" title="RFC 7469 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc7469.txt" title="RFC 7469 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc7469.html" title="RFC 7469 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc7469.txt.pdf" title="RFC 7469 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc7469.txt" title="RFC 7469 : au format Text">TXT</a>
	</dd>
</dl>

<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur la technologie SSL nommée HPKP, liée à la RFC 7469]]></summary>
        <published>2017-08-14T01:56:28+02:00</published>
        <updated>2017-08-16T12:05:15+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3d9874c4-888e-a144-ddcd-e44e84369e9b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/xenodm/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: xenodm : Gestionnaire de sessions X pour OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="xenodm" scheme="http://doc.huc.fr.eu.org/fr/tags/xenodm/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>xenodm</strong> est un gestionnaire de sessions X, fourni dans le système de
base d&rsquo;OpenBSD, depuis 6.1 - le serveur X et les sessions graphiques !</p>
<p>C&rsquo;est un dérivé du gestionnaire <code>xdm</code>, purgé de beaucoup de codes, donc
plus léger, et débarrassé de potentielles failles de sécurités :</p>
<blockquote>
Time has passed by and nowadays, xdm(1) is mainly used just to manage the
local X server running on laptop or desktop machines. Moreover `XDCMP's
security is weak (based on DES) and doesn't support IPv6 well. So it's
time to retire it. So Xenocara is getting a “new” X Display Manager which
will be called “xenodm”.
<p>Xenodm is based on xdm source code. I&rsquo;ve removed all support for XDMCP
and other old cruft like ugly games with signals and setjmp(3)/longjmp(3)
to set timeouts on potentially blocking operations. Another goal was to
un-tangle the ifdef maze that supported various flavors of authentication
methods, to only keep the BSDauth code used in OpenBSD.</p>
</blockquote>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : <br>
Ne pas utiliser <code>xenodm</code> avec l&rsquo;environnement graphique Gnome3 !</p>
<p>Pour Gnome : Il est <strong>fortement recommandé d&rsquo;utiliser GDM</strong>.</p>
</div>

<h2 id="configuration">Configuration</h2>
<p>Tous les fichiers de configuration se trouvent normalement être sur :
<code>/etc/X11/xenodm/</code></p>
<p>Quelques explications :</p>
<h3 id="xenodm-config">xenodm-config</h3>
<p>Le fichier <code>/etc/X11/xenodm/xenodm-config</code> est le fichier de configuration
central du serveur xenodm. Il &ldquo;redirige&rdquo; vers les autres fichiers de
configuration spécifique… certains sont décrits ci-dessous.</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Créer vos fichiers personnels, tel quel dans <code>~/.config/xenodm/</code> ; faites
vos modifications dedans, puis modifier les variables <code>DisplayManager*</code>
dans le fichier <code>/etc/X11/xenodm/xenodm-config</code> en la faisant pointer
vers vos fichiers personnels !</p>
<p>Mais <strong>attention à chaque upgrade</strong> de version d&rsquo;OpenBSD, certains paramètres
pourraient être dysfonctionnels - si vous avez des problèmes de connexion
avec votre configuration personnalisée de xenodm, il serait plus prudent
de repartir sur la base des fichiers originaux.</p>
</div>

<h4 id="auto-connexion">Auto-connexion</h4>
<p>Vous désirez vous connecter automatiquement avec votre identifiant, sans
avoir à le saisir constamment ?</p>
<p>Ajouter la variable suivante <code>DisplayManager._0.autoLogin</code>, de telle manière : <br>
<code>DisplayManager._0.autoLogin:    Identifiant</code></p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>ATTENTION</strong> : du fait de ne pas avoir à taper votre mot-de-passe,
toute personne peut utiliser votre ordinateur et entrer directement dans
votre session, avec tous les risques que cela comporte : vols d&rsquo;informations,
modifications voire suppressions de documents, etc…</div>

<h4 id="xenodm-config--exemple">xenodm-config : Exemple</h4>
<p>Exemple de fichier <code>etc/X11/xenodm/xenodm-config</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">! $OpenBSD: xenodm-config.cpp,v 1.1 2016/10/23 08:30:37 matthieu Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager.authDir: /etc/X11/xenodm</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager.errorLogFile:    /var/log/xenodm.log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager.keyFile:         /etc/X11/xenodm/xenodm-keys</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager.servers:         /etc/X11/xenodm/Xservers</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!DisplayManager*resources:      /etc/X11/xenodm/Xresources</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*resources:       /home/UserId/.config/xenodm/Xresources</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! All displays should use authorization, but we cannot be sure</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! X terminals may not be configured that way, so they will require</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! individual resource settings.</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*authorize:       true</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*startup:         /etc/X11/xenodm/Xstartup</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*session:         /etc/X11/xenodm/Xsession</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*reset:           /etc/X11/xenodm/Xreset</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*authComplain:    true</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! The following three resources set up display :0 as the console.</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!DisplayManager._0.setup:       /etc/X11/xenodm/Xsetup_0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager._0.setup:        /home/UserId/.config/xenodm/Xsetup_0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!DisplayManager._0.startup:     /etc/X11/xenodm/GiveConsole</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager._0.startup:      /home/UserId/.config/xenodm/GiveConsole</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager._0.reset:        /etc/X11/xenodm/TakeConsole</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager.*.authName:      MIT-MAGIC-COOKIE-1</span>
</span></span></code></pre></div><ul>
<li>Les lignes commençant par un <code>!</code> sont toutes des lignes de commentaires.</li>
<li>Par principe de précaution, j&rsquo;ai dédoublé les lignes <code>DisplayManager*resources</code>,
<code>DisplayManager._0.setup</code>, <code>DisplayManager._0.startup</code> en commentant
celles en rapport avec les fichiers dans le répertoire de configuration
principal, pour paramétrer ceux de fichiers dans le $HOME.</li>
<li>Remplacez <code>UserId</code> par votre identifiant de session…</li>
</ul>
<h3 id="xresources">Xresources</h3>
<p>Le fichier <code>/etc/X11/xenodm/Xresources</code> permet de modifier l&rsquo;apparence
du gestionnaire <em>(couleurs, polices, textes, etc.)</em>.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce fichier NE doit PAS avoir des droits en exécution !</div>

<hr>
<h4 id="arrêter-lexécution-de-xenodm">Arrêter l&rsquo;exécution de xenodm</h4>
<p>Pour sortir de l&rsquo;exécution de xenodm, il est nécessaire de configurer le
fichier Xresources afin d&rsquo;ajouter ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.login.translations: #override \</span>
</span></span><span style="display:flex;"><span>  <span style="color:#06b6ef">Ctrl&lt;Key&gt;R: abort-display()</span>
</span></span></code></pre></div><p>Cette astuce permet de basculer en mode console, en arrêtant le serveur
de xenodm, par l&rsquo;appui sur les touches <kbd>Ctrl+R</kbd>.</p>
<h4 id="interdire-la-connexion-root">Interdire la connexion root</h4>
<p>Pour interdire la connexion du compte root, il faut modifier ce fichier
de configuration et décommenter la ligne 128, de telle manière :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.allowRootLogin:    false</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ceci est une recommandation pratique de sécurité !</div>

<h4 id="xresource--exemple-personnalisé">Xresource : Exemple personnalisé</h4>
<p>Exemple personnalisé du fichier <code>$HOME/.config/xenodm/Xresource</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">! $OpenBSD: Xresources.in,v 1.1 2017/07/26 21:14:54 matthieu Exp $</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DisplayManager*terminateServer: true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! ----------------------------------------------------------------------</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! XLogin</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.allowRootLogin: false</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.echoPasswd:   false</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.fail:         Authorization failed</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.greeting:</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.namePrompt:</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.passwdPrompt:</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.y:                340</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.width:            480</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin*borderWidth:            0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.frameWidth:       0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.innerFramesWidth: 0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.sepWidth:         0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.face:       DejaVu Sans-16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.failFace:   DejaVu Sans-18:bold</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.greetFace:  DejaVu Sans-0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xlogin.Login.promptFace: DejaVu Sans-18</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! ----------------------------------------------------------------------</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">! XMessage</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!xmessage*background: nord0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">!xmessage*foreground: nord4</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmessage*borderWidth: 0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmessage*font: -*-terminus-bold-*-*-*-16-*-*-*-*-*-iso8859-15</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmessage*message.scrollHorizontal: Never</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmessage*message.scrollVertical: Never</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">xmessage*timeout: 0</span>
</span></span></code></pre></div><h3 id="xsession">Xsession</h3>
<p>Le fichier <code>/etc/X11/xenodm/Xsession</code> s&rsquo;occupe de l&rsquo;entrée en session
personnelle.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce fichier doit avoir des droits en exécution !</div>

<p>Un peu de décryptage utile :</p>
<ul>
<li>création et gestion d&rsquo;un fichier personnel <code>~/.xsession-errors</code>, dont
le but est de permettre au système d&rsquo;écrire dedans tout problème
relatif à l&rsquo;exécution de l&rsquo;entrée en session. C&rsquo;est le fichier à
vérifier IMPÉRATIVEMENT si vous rencontrez des problèmes de connexion.</li>
<li>gestion de l&rsquo;agent SSH - si celui-ci est installé ET fonctionnel,
c&rsquo;est la raison pour laquelle il est demandé la saisie des clés SSH
lors de la connexion. Si erreur, la session se fermera immédiatement.</li>
<li>gestion du fichier personnel <code>~/.xsession</code> :
<ul>
<li>si le fichier existe ET qu&rsquo;il n&rsquo;est pas vide, il sera exécuté.</li>
<li>si le fichier a des droits en exécution, il sera appelé directement
<ul>
<li>à ce propos, il est recommandé dans le
<a href="https://man.openbsd.org/xenodm.1#SESSION_PROGRAM" rel="external">manpage</a> que
celui-ci <strong>doit avoir</strong> ces fameux droits.</li>
</ul>
</li>
<li>s&rsquo;il n&rsquo;a pas de droits en exécution, un appel système au shell
sera fait pour l&rsquo;exécuter.</li>
<li>si le fichier n&rsquo;existe pas, le système vérifiera l&rsquo;existence d&rsquo;un
fichier personnel <code>~/.Xresources</code> - <em>copie personnelle du fichier
<code>/etc/X11/xenodm/Xresources</code></em> - pour le charger, ainsi exécuter
les binaires <code>xterm</code>, et <code>fvwm</code> par défaut. C&rsquo;est le seul cas,
où si ce fichier existe, il sera lu…</li>
</ul>
</li>
</ul>
<h3 id="xsetup_0">Xsetup_0</h3>
<p>Le fichier <code>/etc/X11/xenodm/Xsetup_0</code> nous permet d&rsquo;utiliser des binaires
X, tels que <code>xconsole</code> <em>(c&rsquo;est la fameuse console de log qui s&rsquo;affiche
par défaut)</em>, <code>xclock</code>, <code>display</code>, etc.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce fichier doit avoir des droits en exécution !</div>

<p>Exemple de fichier <code>/etc/X11/xenodm/Xsetup_0</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: Xsetup_0,v 1.1 2016/10/23 08:30:37 matthieu Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if [ &#34;$DISPLAY&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;:0&#34; -o &#34;$DISPLAY&#34; = &#34;:0.0&#34; ]</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">then</span>
</span></span><span style="display:flex;"><span>       <span style="color:#06b6ef">xconsole -geometry 480x130-0-0 -daemon -notify -verbose -fn fixed -exitOnFail</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span></code></pre></div><p>⇒ <code>display</code> permet, entres autres, d&rsquo;avoir une image en fond d&rsquo;écran… <br>
<code>/usr/local/bin/display -window root /home/user/Images/Wallpapers/OBSD_From_Dark_to_the_Light.png</code> <br>
<em>(Retrouvez l&rsquo;<a href="https://huc.fr.eu.org/img/EBNH/OBSD/OBSD_From_Dark_to_the_Light.png" rel="external">image</a> en question…)</em></p>
<p>⇒ <code>qiv</code> permet, entres autres, d&rsquo;avoir un fond d&rsquo;écran aléatoire, selon
les options fournies… à chaque fois que xenodm est relancé ! <br>
<code>/usr/local/bin/qiv -zr /home/user/Images/Wallpapers/* &amp;</code> <br>
<em>(cet outil ne fait pas partie du système de base).</em></p>
<p>⇒ <code>xclock</code> permet d&rsquo;afficher une horloge…  <br>
<code>/usr/X11R6/bin/xclock -d -update 1 -render &amp;</code></p>
<p>Pour fermer automatiquement l&rsquo;horloge, on récupère son id - dans le fichier
<code>Xsetup_0</code>, sous la ligne déclarant le binaire, <abbr title="exemplī grātia">e.g.</abbr>
 : <br>
<code>echo $! &gt; /var/run/xclock.pid</code></p>
<h4 id="exemple-personnalisé">Exemple personnalisé</h4>
<p>Exemple personnalisé du fichier <code>$HOME/.config/xenodm/Xsetup_0</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/ksh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: Xsetup_0,v 1.1 2016/10/23 08:30:37 matthieu Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if [ &#34;$DISPLAY&#34;</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;:0&#34; -o &#34;$DISPLAY&#34; = &#34;:0.0&#34; ]; then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">BG_COLOR</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$(/usr/X1R6/bin/xrdb -query | awk &#39;/xroot.background/ { print $2 }&#39;)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    OS_NAME=$(uname -n)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    OS_INFO=$(uname -smr)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    USER=id_user    # changer par votre identifiant utilisateur</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/X11R6/bin/xrandr --output default --dpi 96</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/X11R6/bin/xset fp+ /usr/local/share/fonts/roboto</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/X11R6/bin/xsetroot -solid $BG_COLOR</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># obtenir un fichier aléatoire dans un répertoire précis</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">set +A files /home/$USER/Images/OpenBSD-Art/*</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">N</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">${#files[@]}           # Number of members in the array
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ((N=RANDOM%N))
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    img=${files[$N]}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/local/bin/feh -b --bg-center -B $BG_COLOR -. -Z $img &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/local/bin/qiv -zrd7 /home/$USER/Images/Wallpapers/* &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># menu</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">(</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">while true; do</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">/usr/X11R6/bin/xmessage -center \</span>
</span></span><span style="display:flex;"><span>         <span style="color:#06b6ef">-buttons &#34;[ Sleep ]&#34;:20,&#34;[ Restart ]&#34;:21,&#34;[ Shutdown ]&#34;:22 &#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#06b6ef">ACTION</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$?
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        echo &#34;Xmessage said: $ACTION&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        if   [ $ACTION -eq 20 ]; then /usr/sbin/zzz;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        elif [ $ACTION -eq 21 ]; then
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">            /usr/X11R6/bin/xsetroot -cursor_name watch
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">            /sbin/shutdown -r now
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        elif [ $ACTION -eq 22 ]; then
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">            /usr/X11R6/bin/xsetroot -cursor_name watch
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">            /sbin/shutdown -p now
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        else echo &#34;Something bad happened to Xmessage.&#34;;
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        fi
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        # stop looping if xclock died (hopefully killed by GiveConsole)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        if [ -z &#34;$(pgrep -U root /usr/X11R6/bin/xclock)&#34; ]; then break; fi
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    done
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">    ) &amp;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">/usr/X11R6/bin/xclock -geometry -0+0 -d -update 1 -render \</span>
</span></span><span style="display:flex;"><span>      <span style="color:#06b6ef">-strftime &#34;$OS_NAME ($OS_INFO) | %a. %d %b. %Y  %H:%M:%S &#34; &amp;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#/usr/X11R6/bin/xclock -d -update 1 -render &amp;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">echo $! &gt; /var/run/xclock.pid</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sxpm OpenBSD.xpm &amp;</span>
</span></span></code></pre></div><p>À la différence, mon fichier appelle le shell <code>ksh</code>, car pour définir un
fichier image aléatoire, je définis :</p>
<ul>
<li>un tableau nommé <code>files</code> dans lequel est attribué les noms de fichiers
du répertoire cible…</li>
<li>la variable <code>N</code> qui, dans un premier temps, définit le nombre d&rsquo;éléments
du tableau <code>files</code>, puis après être passer par un calcul <code>RANDOM</code>,</li>
<li>la variable <code>img</code> qui est attribué selon le <code>N</code>ème élément du tableau
<code>files</code>, qui est ensuite appelé par le logiciel <code>feh</code>.</li>
</ul>
<p>Normalement, <code>feh</code> devrait afficher l&rsquo;image au centre de l&rsquo;écran… <br>
<em>ça bogue, puisque elle est affichée depuis le haut à gauche</em>.</p>
<p>La boucle <code>while</code> permet d&rsquo;afficher un menu linéaire, sous la zone de saisie
de session, affichant : <code>[ Sleep ] [ Restart ] [ Shutdown ]</code>.  <br>
Cliquer avec la souris sur l&rsquo;une ou l&rsquo;autre des actions permet de déclencher
l&rsquo;action nommée.</p>
<p>Pour l&rsquo;exécution correcte de ce script <code>Xsetup_0</code>, il faudra installer par
le biais du gestionnaire de paquets, et <code>feh</code>, et <code>qiv</code>.</p>
<h3 id="giveconsole">GiveConsole</h3>
<p>Le fichier <code>/etc/X11/xenodm/GiveConsole</code> a pour propos de traiter des
instructions en sortie de xenodm.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Ce fichier doit avoir des droits en exécution !</div>

<h4 id="exemple-personnalisé-1">Exemple personnalisé</h4>
<p>Exemple personnalisé du fichier <code>$HOME/.config/xenodm/GiveConsole</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Assign ownership of the console to the invoking user</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: GiveConsole,v 1.1 2016/10/23 08:30:37 matthieu Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># By convention, both xconsole and xterm -C check that the</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># console is owned by the invoking user and is readable before attaching</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># the console output.  This way a random user can invoke xterm -C without</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># causing serious grief.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">chown $USER /dev/console</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if [ -c /dev/drm0 ]; then</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">chown $USER /dev/drm0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/usr/X11R6/bin/sessreg -a -l $DISPLAY -u none -x /etc/X11/xenodm/Xservers $USER</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">if test -r /var/run/xclock.pid; then kill $(cat /var/run/xclock.pid); fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pkill feh</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pkill xmessage</span>
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/xenodm" title="Page du Manuel OpenBSD pour : xenodm">xenodm</a>
</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Explications sur le serveur graphique xenodm sous OpenBSD et personnalisations]]></summary>
        <published>2017-08-06T19:29:05+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8d5abdae-d713-6488-b4ff-0fc0699b1153</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/signify/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: [Mini-Tuto] Signify (OpenBSD)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Signify" scheme="http://doc.huc.fr.eu.org/fr/tags/signify/" />
        <category term="Mini-Tuto" scheme="http://doc.huc.fr.eu.org/fr/tags/mini-tuto/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un mini-tutoriel concernant l&rsquo;usage de l&rsquo;outil 
<a class="man" href="https://man.openbsd.org/signify" title="Page du Manuel OpenBSD pour : signify">signify</a>
 !</p>
<p>Pour ceux qui ne connaissent pas, <em>signify</em> est un outil natif du projet
OpenBSD, dont le but est de générer une signature cryptographique d&rsquo;un
fichier ou ensemble de fichiers.</p>
<h2 id="vérification-de-signature">Vérification de signature</h2>
<p>Vous avez récupéré un fichier de clé publique, créé avec signify, ainsi
que le fichier de signature ; pour vérifier que les fichiers fournis
avec soient intègres, il vous faudra utiliser signify ainsi : <br>
<code>:$ signify -C -p Nom_Projet.pub -x Nom_Projet.sig</code></p>
<p>Cette commande signifie de vérifier avec la clé publique du projet
Untel, tous les fichiers écrites dans le fichier de signature.</p>
<p>Cette commande peut être légèrement abrégée : <br>
<code>:$ signify -Cp Nom_Projet.pub -x Nom_Projet.sig</code></p>
<h2 id="création-de-signature">Création de signature</h2>
<p>Maintenant, voyons comment créer un ensemble de fichiers de clé
privée/publique avec signify : <br>
<code>:$ signify -G -p Nom_Projet.pub -s Nom_Projet.sec</code></p>
<p>L&rsquo;invite de commande vous demandera d&rsquo;écrire une passphrase et de la
confirmer !</p>
<span class="red">Ne pas oublier la passphrase ; et, mettez en sécurité le
fichier de clé privée `*.sec`, en lieu sûr !</span>

<p>Si pour des raisons quelconques, vous avez besoin de générer une
signature sans passphrase, exécutez signify ainsi : <br>
<code>:$ signify -G -n -p Nom_Projet.pub -s Nom_Projet.sec</code></p>
<h2 id="génération-du-fichier-de-signature">Génération du fichier de signature</h2>
<p>Nous savons donc vérifier un ensemble de fichiers grâce à un fichier de
signature, créer un ensemble de clé privée/publique, voyons comment
générer un fichier de signature !</p>
<p><code>:$ signify -S -e -x Nom_Projet.sig -s Nom_Projet.sec</code></p>
<h3 id="cas-dutilisation">Cas d&rsquo;utilisation</h3>
<p>Profitons de la possibilité de coupler l&rsquo;outil signify, avec une fonction de
hachage cryptographique, telle <code>sha512</code> !</p>
<ul>
<li>En premier lieu, générons un fichier de condensats cryptographiques, e.g : <br>
<code>:$ find ./ -exec sha512 {} + &gt; Nom_Projet.sha512</code></li>
<li>Puis, occupons nous du fichier de signature : <br>
<code>:$ signify -S -s Nom_Projet.sec -m Nom_Projet.sha512 -e -x Nom_Projet.sig</code></li>
</ul>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">À-propos de l&rsquo;usage de l&rsquo;algorithme de cryptographie sha512 : <br>
La génération de hashes cryptographiques peut être faite par l&rsquo;outil <code>cksum</code>
en utilisant l&rsquo;option <code>-a</code> pour cibler l&rsquo;algorithme <code>sha512</code> <em>(entres autres…)</em> !</div>

<hr>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Le terme &ldquo;somme de contrôle&rdquo; est communément accepté pour parler des
condensats/hashes cryptos générés à partir d&rsquo;une fonction de hash. Cet usage
peut être considéré comme impropre par des spécialistes. Par exemple,
pour explication :</p>
<hr>
<p>Une somme de contrôle est utile pour détecter des modifications accidentelles
des données, mais n&rsquo;a pas vocation à assurer une protection contre les
modifications intentionnelles. Plus précisément, elle ne peut en général pas
assurer directement l&rsquo;intégrité cryptographique des données. Pour éviter de
telles modifications, il est possible d&rsquo;utiliser une fonction de hachage adaptée,
comme SHA-256, couplée à un élément secret (clé secrète), ce qui correspond au
principe du HMAC. <em><a href="https://fr.wikipedia.org/wiki/Somme_de_contr%C3%B4le#Somme_de_contr%C3%B4le_et_cryptographie" rel="external">source</a></em></p>
</div>

<h2 id="documentation">Documentation</h2>
<ul>
<li>Le manpage officiel - <em>en anglais</em> - : 
<a class="man" href="https://man.openbsd.org/signify" title="Page du Manuel OpenBSD pour : signify">signify</a>
</li>
<li>Celui de la fonction de hachage cryptographique - <em>en anglais</em> - : 
<a class="man" href="https://man.openbsd.org/sha512" title="Page du Manuel OpenBSD pour : sha512">sha512</a>
</li>
<li>Celui à-propos de l&rsquo;outil en ligne de commande - <em>en anglais</em> - : 
<a class="man" href="https://man.openbsd.org/cksum" title="Page du Manuel OpenBSD pour : cksum">cksum</a>
</li>
<li>La page <a href="https://fr.wikipedia.org/wiki/Somme_de_contr%c3%b4le" title="Article Wikipédia : Somme_de_contrôle">Somme_de_contrôle <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Petit rappel pour l&#39;utilisation de l&#39;outil signify sous OpenBSD.]]></summary>
        <published>2017-07-31T13:50:49+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:adac398c-5550-5ea5-9f93-db4fb73d57a3</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/usb-thetering-urndis/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: OpenBSD : USB Thetering (urndis)… Partage de connexion réseau</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="USB" scheme="http://doc.huc.fr.eu.org/fr/tags/usb/" />
        <category term="Thetering" scheme="http://doc.huc.fr.eu.org/fr/tags/thetering/" />
        <category term="urndis" scheme="http://doc.huc.fr.eu.org/fr/tags/urndis/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>L&rsquo;USB Thetering est le partage d&rsquo;une connexion réseau, depuis votre smartphone
avec votre station informatique.</p>
<p>Votre connexion réseau, telle celle d&rsquo;internet, sur votre smartphone, peut
soit venir du Wifi, soit d&rsquo;une connexion 3G/4G.</p>
<hr>
<ul>
<li>Testé sur OpenBSD 6.x - <em>Driver urndis(4)</em></li>
<li>Smartphone utilisé :
<ul>
<li>Xiaomi Redmi - Android 4.4.2 <em>(KitKat)</em></li>
<li>Xiaomi Mi A2 Lite - Android 9, 10</li>
</ul>
</li>
<li>Testé : partage de connexion par Wifi, 3G/4G</li>
</ul>
<h2 id="configuration">Configuration</h2>
<ol>
<li>
<p>Connectez votre smartphone à Internet, et vérifiez que vous pouvez bien
surfez avec.</p>
</li>
<li>
<p>Connectez le smartphone par USB à votre station OpenBSD, puis vérifiez
aussitôt la connexion :</p>
</li>
</ol>
<pre tabindex="0"><code>:$ dmesg | tail -n1
ugen0 at uhub0 port 2 &#34;MediaTek MT65xx Android Phone&#34; rev 2.00/2.16 addr 2
</code></pre><p><em>Dans cet exemple, le téléphone est ici reconnu comme un Android Phone.</em></p>
<ol start="3">
<li>Selon votre version d&rsquo;Android :
<ul>
<li>Activer la fonction &ldquo;USB Thetering&rdquo; : &ldquo;Menu Système&rdquo; &gt; &ldquo;More&rdquo; &gt; &ldquo;USB Thetering&rdquo; -
<em>(Android KitKat)</em></li>
<li>ou, Menu &ldquo;Réseau et Internet&rdquo; : Point d&rsquo;accès et partage de connexion &gt; Via USB -
<em>(Android 9, 10)</em></li>
</ul>
</li>
</ol>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Le menu pour activer la fonction peut être sensiblement différent, selon
la marque de votre téléphone, la version du système d&rsquo;exploitation utilisé,
et la langue utilisée sur votre smartphone.</p>
<p><em>(Celui de l&rsquo;exemple est celui d&rsquo;une ROM MIUI 8)</em></p>
</div>

<p>Puis, vérifiez aussitôt :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ dmesg | tail -n3
</span></span><span style="display:flex;"><span>urndis0 at uhub0 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;MediaTek MT65xx Android Phone&#34;</span> rev 2.00/2.16 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>urndis0: using RNDIS, address f2:5d:d2:80:94:b5
</span></span><span style="display:flex;"><span>ugen0 at uhub0 port <span style="color:#f99b15">2</span> configuration <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;MediaTek MT65xx Android Phone&#34;</span> rev 2.00/2.16 addr <span style="color:#f99b15">2</span>
</span></span></code></pre></div><p>Coup de chance, nous avons le pilote <strong>urndis</strong>… il se comporte comme un
pilote réseau pour communiquer entre le smartphone - <em>généralement des
Android</em> - et la station, par le biais du port USB.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si vous n&rsquo;avez pas ce message, ou si vous avez tout autre message :
n&rsquo;allez pas plus loin, la suite de ce tutoriel ne vous servira pas !</div>

<ol start="4">
<li>Puisque c&rsquo;est un pilote <strong>Ethernet</strong>, alors simplifions-nous la vie
avec <code>ifconfig</code> :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ifconfig urndis0
</span></span><span style="display:flex;"><span>urndis0: <span style="color:#ef6155">flags</span><span style="color:#5bc4bf">=</span>8802&lt;BROADCAST,SIMPLEX,MULTICAST&gt; mtu <span style="color:#f99b15">1500</span>
</span></span><span style="display:flex;"><span>        lladdr f2:5d:d2:80:94:b5
</span></span><span style="display:flex;"><span>        index <span style="color:#f99b15">70</span> priority <span style="color:#f99b15">0</span> llprio <span style="color:#f99b15">3</span>
</span></span></code></pre></div><ol start="5">
<li>Paramétrons le fichier <code>/etc/hostname.urndis0</code>&rsquo;, pour y ajouter au moins
la valeur <code>dhcp</code>, à minima… <br>
<strong>Faites un chmod 0640 dessus !!!</strong></li>
</ol>
<p>Puis demandons une adresse IP :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# dhclient urndis0
</span></span><span style="display:flex;"><span>DHCPREQUEST on urndis0 to 255.255.255.255
</span></span><span style="display:flex;"><span>DHCPNACK from 192.168.42.129 <span style="color:#5bc4bf">(</span>06:45:e6:2f:3f:51<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>DHCPDISCOVER on urndis0 - interval <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>DHCPDISCOVER on urndis0 - interval <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>DHCPDISCOVER on urndis0 - interval <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>DHCPOFFER from 192.168.42.129 <span style="color:#5bc4bf">(</span>06:45:e6:2f:3f:51<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>DHCPREQUEST on urndis0 to 255.255.255.255
</span></span><span style="display:flex;"><span>DHCPACK from 192.168.42.129 <span style="color:#5bc4bf">(</span>06:45:e6:2f:3f:51<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>bound to 192.168.42.125 -- renewal in <span style="color:#f99b15">21600</span> seconds.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:$ ifconfig urndis0
</span></span><span style="display:flex;"><span>urndis0: <span style="color:#ef6155">flags</span><span style="color:#5bc4bf">=</span>8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu <span style="color:#f99b15">1500</span>
</span></span><span style="display:flex;"><span>        lladdr f2:5d:d2:80:94:b5
</span></span><span style="display:flex;"><span>        index <span style="color:#f99b15">70</span> priority <span style="color:#f99b15">0</span> llprio <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>        inet 192.168.42.125 netmask 0xffffff00 broadcast 192.168.42.255
</span></span></code></pre></div><ol start="6">
<li>Pour un démarrage automatique de <code>dhcp</code> lors du montage du périphérique,
on modifie le fichier <code>/etc/hotplug/attach</code>, ainsi :</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span>       <span style="color:#06b6ef">3)</span>
</span></span><span style="display:flex;"><span>       <span style="color:#776e71"># network devices; requires hostname.$DEVNAME</span>
</span></span><span style="display:flex;"><span>       <span style="color:#06b6ef">sh /etc/netstart $DEVNAME</span>
</span></span><span style="display:flex;"><span>       <span style="color:#776e71">;;</span>
</span></span></code></pre></div><h3 id="pf">PF</h3>
<p>Selon vos règles PF, si vous en avez, selon comme elles sont construites,
il est certainement préférable de relancer PF !</p>
<h2 id="test">Test</h2>
<p>Maintenant, testez votre connexion Internet depuis votre station OpenBSD.
Et, zou, la patate… 😃</p>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ifconfig.8" title="Page du Manuel OpenBSD pour : ifconfig">ifconfig(8)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/urndis.4" title="Page du Manuel OpenBSD pour : urndis">urndis(4)</a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment faire un partage de connexion internet avec votre smartphone par USB sous OpenBSD - urndis(4)]]></summary>
        <published>2017-07-31T12:10:35+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:13e198b3-f739-f523-1bc7-ee0e1b3a05fb</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/shell/split-archive/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Shell : découper/reconstruire une archive…</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="shell" scheme="http://doc.huc.fr.eu.org/fr/tags/shell/" />
        <category term="archive" scheme="http://doc.huc.fr.eu.org/fr/tags/archive/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le code ci-dessous compresse le fichier archive et le découpe par tranche
de 100 Mo, en ajoutant une extension incrémentée alphabétique… <br>
<em>(tel que : <code>_aa</code> pour le premier fichier, <code>_ab</code> pour le second, <code>_ac</code> pour le
troisième, etc…)</em></p>
<h2 id="découper">Découper</h2>
<h3 id="découper-une-archive-tar">Découper une archive tar</h3>
<p>Pour découper une archive tar, utilisons le binaire <strong>split</strong> :</p>
<p><code>tar cz fichier | split -b 100m - archive_split.tgz_</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention : sous OpenBSD, tar supporte mal les gros fichiers et se mettra en
erreur !</div>

<h3 id="découper-une-archive-gzip">Découper une archive gzip</h3>
<p>Pour découper votre archive au format gzip :</p>
<p><code>gzip -c fichier | split -b 100m - archive_split.gz_</code></p>
<h2 id="reconstruire">Reconstruire</h2>
<p>Dans un premier temps, il nous faut &ldquo;concaténer&rdquo; l&rsquo;archive, nous utiliserons
dans les deux cas l&rsquo;outil <strong>cat</strong>, puis ensuite il faut la décompresser
pour obtenir le(s) fichiers(s) de l&rsquo;archive.</p>
<h3 id="reconstruire-larchive-tar">Reconstruire l&rsquo;archive tar</h3>
<p><code>cat archive_split.tgz_* | tar xz</code></p>
<h3 id="reconstruire-larchive-gzip">Reconstruire l&rsquo;archive gzip</h3>
<p><code>cat archive_split.gz_* | gunzip -c &gt; fichier</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment découper une archive tar, .gz, .bz dans un shell (Bash, ksh), puis la reconstruire !]]></summary>
        <published>2017-07-31T00:00:00+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:37d51460-0db4-3d41-e85e-7b898e4abbb1</id>
        <link href="http://doc.huc.fr.eu.org/fr/post/split-archive/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Shell : découper/reconstruire une archive…</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="shell" scheme="http://doc.huc.fr.eu.org/fr/tags/shell/" />
        <category term="archive" scheme="http://doc.huc.fr.eu.org/fr/tags/archive/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le code ci-dessous compresse le fichier archive et le découpe par tranche
de 100 Mo, en ajoutant une extension incrémentée alphabétique… <br>
<em>(tel que : <code>_aa</code> pour le premier fichier, <code>_ab</code> pour le second, <code>_ac</code> pour le troisième, etc…)</em></p>
<h2 id="découper">Découper</h2>
<h3 id="découper-une-archive-tar">Découper une archive tar</h3>
<p>Pour découper une archive tar, utilisons le binaire <strong>split</strong> :</p>
<p><code>tar cz fichier | split -b 100m - archive_split.tgz_</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention : sous OpenBSD, tar supporte mal les gros
fichiers et se mettra en erreur !</div>

<h3 id="découper-une-archive-gzip">Découper une archive gzip</h3>
<p>Pour découper votre archive au format gzip :</p>
<p><code>gzip -c fichier | split -b 100m - archive_split.gz_</code></p>
<h2 id="reconstruire">Reconstruire</h2>
<p>Dans un premier temps, il nous faut &ldquo;concaténer&rdquo; l&rsquo;archive, nous utiliserons
dans les deux cas l&rsquo;outil <strong>cat</strong>, puis ensuite il faut la décompresser
pour obtenir le(s) fichiers(s) de l&rsquo;archive.</p>
<h3 id="reconstruire-larchive-tar">Reconstruire l&rsquo;archive tar</h3>
<p><code>cat archive_split.tgz_* | tar xz</code></p>
<h3 id="reconstruire-larchive-gzip">Reconstruire l&rsquo;archive gzip</h3>
<p><code>cat archive_split.gz_* | gunzip -c &gt; fichier</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment découper une archive tar, .gz, .bz dans un shell (Bash, ksh), puis la reconstruire !]]></summary>
        <published>2017-07-31T00:00:00+01:00</published>
        <updated>2023-04-15T15:56:49+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0e6dc0b4-00cd-352a-ca58-8c2186106fd7</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/php/php-warning-unknown-unable-to-create-temporary-file/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP Warning:  Unknown: Unable to create temporary file</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP" scheme="http://doc.huc.fr.eu.org/fr/tags/php/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="Unknown" scheme="http://doc.huc.fr.eu.org/fr/tags/unknown/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Dans vos logs d&rsquo;erreur web, vous avez le message d&rsquo;erreur suivant :</p>
<p><code>FastCGI sent in stderr: &quot;PHP message: PHP Warning:  Unknown: Unable to create temporary file, Check permissions in temporary files directory. in Unknown on line 0</code></p>
<p>Ou celui-ci, qui est sensiblement différent :</p>
<p><code>PHP Warning:  File upload error - unable to create a temporary file in Unknown on line 0</code></p>
<p>Le problème est très simple: PHP ne peut pas créer les fichiers temporaires
dont il a besoin de créer, dans le répertoire temporaire indiqué dans votre
fichier de configuration <code>/etc/php-fpm.d/$domain.conf</code>.</p>
<h2 id="dépannage">Dépannage</h2>
<p>Ouvrez votre fichier de configuration php-fpm relatif à votre site web.</p>
<p>Vérifiez les informations suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">user</span> <span style="color:#5bc4bf">=</span> ???
</span></span><span style="display:flex;"><span><span style="color:#ef6155">group</span> <span style="color:#5bc4bf">=</span> ???
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>env<span style="color:#5bc4bf">[</span>TMP<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> /var/www/tmp
</span></span><span style="display:flex;"><span>env<span style="color:#5bc4bf">[</span>TMPDIR<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> /var/www/tmp
</span></span><span style="display:flex;"><span>env<span style="color:#5bc4bf">[</span>TEMP<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> /var/www/tmp
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>php_admin_value<span style="color:#5bc4bf">[</span>upload_tmp_dir<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">=</span> /tmp
</span></span></code></pre></div><p>Relevez les informations relatives à <code>user</code>, <code>group</code>, et <code>env[TMP]</code></p>
<ul>
<li>Vérifiez que le répertoire nommé dans les variables <code>env</code> ait bien les droits
utilisateurs liés à <code>user:group</code>.</li>
<li>Vérifiez les droits en écriture… <em>sous OpenBSD, sous Debian/Ubuntu, des droits
0705 semblent fonctionnels</em>, à défaut 0755 devraient remédier à la situation !</li>
<li>Si <code>php_admin_value[open_basedir]</code> est activée, ou l&rsquo;option <code>open_basedir</code>,
veillez à ajouter le répertoire <code>/tmp</code> parmi les répertoires autorisés !</li>
</ul>
<p><code># chown user:group /var/www/tmp</code></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Vous remarquez que la variable <code>php_admin_value[upload_tmp_dir]</code> pointe vers
<code>/tmp</code>. C&rsquo;est normal, il pointe vers le répertoire temporaire dans le chroot web… <br>
Si le chroot web est <code>/var/www</code>, le répertoire temporaire relatif est bel est
bien <code>/tmp</code>. <br>
Quoiqu&rsquo;il en soit, vérifiez que celui-ci est exactement les mêmes droits
utilisateurs nécessaire à PHP !</div>

<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre l&#39;ensemble d&#39;erreurs liée à &#39;PHP Warning:  Unknown: Unable to create temporary file&#39; !]]></summary>
        <published>2017-07-29T21:42:59+02:00</published>
        <updated>2017-08-14T14:22:43+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:08433240-0676-22fa-3c42-207bf5c1222c</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/php/php-warning-open-basedir-restriction-in-effect/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP Warning: open_basedir restriction in effect</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP" scheme="http://doc.huc.fr.eu.org/fr/tags/php/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="open_basedir" scheme="http://doc.huc.fr.eu.org/fr/tags/open_basedir/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>C&rsquo;est un ensemble de message d&rsquo;erreurs php-fpm !</p>
<p>Elles signifient que vous utilisez la variable <code>php_admin_value[open_basedir]</code>.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="php-warning--is_dir-open_basedir-restriction-in-effect">PHP Warning:  is_dir(): open_basedir restriction in effect</h3>
<p>Vous avez un message ressemblant à celui-ci :</p>
<p><code>[error] 85001#0: *47 FastCGI sent in stderr: &quot;PHP message: PHP Warning:  is_dir(): open_basedir restriction in effect. File(/var/www/cache/) is not within the allowed path(s): (/htdocs/:/var/www/cache/:/logs/:/run/:/tmp/) in /htdocs/www/dc/master/inc/libs/clearbricks/net.http.feed/class.feed.reader.php on line 116&quot; while reading response header from upstream, client: 88.136.16.221, server: www.stephane-huc.net, request: &quot;GET /dc/master/admin/ HTTP/2.0&quot;, upstream: &quot;fastcgi://unix:/run/php-fpm.sock:&quot;, host: &quot;www.stephane-huc.net&quot;</code></p>
<p>Vérifiez :</p>
<ul>
<li>que le répertoire, dans lequel le script php utilisé cherche à
écrire, fasse bien partie des répertoires qui soient autorisés, sinon
ajoutez-le…</li>
<li>et qu&rsquo;il ait bien les droits utilisateur <code>user</code> et <code>group</code> écrits dans
le fichier <code>/etc/php-fpm.d/$domain.conf</code>.</li>
</ul>
<h3 id="php-warning--is_readable-open_basedir-restriction-in-effect">PHP Warning:  is_readable(): open_basedir restriction in effect</h3>
<p>Vous avez un message ressemblant à celui-ci :</p>
<p><code>[error] 85001#0: *47 FastCGI sent in stderr: &quot;PHP message: PHP Warning:  is_readable(): open_basedir restriction in effect. File(/var/www/cache/script.php) is not within the allowed path(s): (/htdocs/:/var/www/cache/:/logs/:/run/:/tmp/) in /htdocs/www/dc/master/inc/core/class.dc.update.php on line 75</code></p>
<p>Vérifiez :</p>
<ul>
<li>que le script utilisé ait les droits utilisateur nécessaires à l&rsquo;exécution
de celui-ci ; cf, les instructions <code>user</code> et <code>group</code> du fichier
<code>/etc/php-fpm.d/$domain.conf</code>.</li>
</ul>
<h3 id="php-warning--require-open_basedir-restriction-in-effect">PHP Warning:  require(): open_basedir restriction in effect</h3>
<p>Vous avez un message ressemblant à celui-ci :</p>
<p><code>[error] 91433#0: *1 FastCGI sent in stderr: &quot;PHP message: PHP Warning:  require(): open_basedir restriction in effect. File(/htdocs/www/dc/master/inc/admin/prepend.php) is not within the allowed path(s): (/htdocs/www:/cache/:/logs/:/run/:/tmp/) in /htdocs/www/dc/master/admin/index.php on line 23 PHP message: PHP Fatal error:  require(): Failed opening required '/htdocs/www/dc/master/admin/../inc/admin/prepend.php' (include_path='.:/pear/lib:/var/www/pear/lib') in /htdocs/www/dc/master/admin/index.php on line 23&quot; while reading response header from upstream, client: 88.136.16.221, server: www.stephane-huc.net, request: &quot;GET /dc/master/admin/ HTTP/2.0&quot;, upstream: &quot;fastcgi://unix:/run/php-fpm.sock:&quot;, host: &quot;www.stephane-huc.net&quot;</code></p>
<p>Vérifiez :</p>
<ul>
<li>que le script appelé soit bien dans les répertoires autorisés,</li>
<li>et qu&rsquo;il ait les droits utilisateur <code>user</code> et <code>group</code> lié à php-fpm…</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre les différentes raisons possibles dont le résultat est l&#39;erreur &#39;PHP Warning: open_basedir restriction in effect&#39; !]]></summary>
        <published>2017-07-29T21:42:59+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3de64cd3-75e4-68ec-3a08-046bec132630</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/bash/function-array-key-exists/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Bash : function array_key_exists()</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Bash" scheme="http://doc.huc.fr.eu.org/fr/tags/bash/" />
        <category term="array" scheme="http://doc.huc.fr.eu.org/fr/tags/array/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><code>array_key_exists()</code> : vérifie l&rsquo;existence d&rsquo;une clé dans un tableau !</p>
<p><em>Équivalent à la function <a href="http://php.net/manual/en/function.array-key-exists.php" rel="external">PHP array_key_exists</a>()</em></p>
<h2 id="code-source">Code source</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#815ba4">function</span> array_key_exists<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   <span style="color:#776e71"># equivalent to PHP array_key_exists</span>
</span></span><span style="display:flex;"><span>   <span style="color:#776e71"># call: array_key_exists key array</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   local <span style="color:#ef6155">key</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> <span style="color:#ef6155">IFS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34; &#34;</span>; shift; read -a array <span style="color:#5bc4bf">&lt;&lt;&lt;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$@</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">array</span>[<span style="color:#ef6155">$key</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]]</span>; <span style="color:#815ba4">then</span> <span style="color:#815ba4">return</span> 0; <span style="color:#815ba4">else</span> <span style="color:#815ba4">return</span> 1; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   unset array key IFS
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><h3 id="paramètres">Paramètres</h3>
<ul>
<li><code>key</code> est la clé à rechercher</li>
<li><code>haystack</code> est le tableau dans lequel chercher</li>
</ul>
<h3 id="valeurs-de-retour">Valeurs de retour</h3>
<ul>
<li>Retourne <code>0</code> pour la clé <code>key</code>, si elle est trouvée dans le tableau <code>haystack</code> ; 
considérez cette valeur comme <code>TRUE</code></li>
<li>Autrement retourne <code>1</code> : considérez cette valeur comme <code>FALSE</code></li>
</ul>
<h2 id="exemple">Exemple</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>declare -a <span style="color:#ef6155">color</span><span style="color:#5bc4bf">=(</span><span style="color:#48b685">&#34;blue&#34;</span>, <span style="color:#48b685">&#34;red&#34;</span>, <span style="color:#48b685">&#34;green&#34;</span>, <span style="color:#48b685">&#34;grey&#34;</span><span style="color:#5bc4bf">)</span>;
</span></span><span style="display:flex;"><span><span style="color:#ef6155">key</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> array_key_exists <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">key</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">color</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   echo <span style="color:#48b685">&#34;key: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">key</span><span style="color:#f99b15">}</span><span style="color:#48b685"> exists!&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>   echo <span style="color:#48b685">&#34;This key: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">key</span><span style="color:#f99b15">}</span><span style="color:#48b685"> not exists!&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Fonction array_key_exists() en bash équivalente à celle de PHP]]></summary>
        <published>2017-07-29T18:56:36+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:220db97e-6c2c-b8ae-b63e-1b08c372c39a</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/bash/function-array-search/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Bash : function array_search()</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Bash" scheme="http://doc.huc.fr.eu.org/fr/tags/bash/" />
        <category term="array" scheme="http://doc.huc.fr.eu.org/fr/tags/array/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><code>array_search()</code> : recherche dans un tableau la clé associée à une valeur</p>
<p><em>Équivalent à la function [<a href="http://php.net/manual/en/function.array-search.php" rel="external">PHP array_search</a></em></p>
<h2 id="code-source">Code source</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#815ba4">function</span> array_search<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># equivalent to PHP array_search</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71"># call: array_search needle array</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    local <span style="color:#ef6155">needle</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> <span style="color:#ef6155">IFS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34; &#34;</span>; shift; read -a array <span style="color:#5bc4bf">&lt;&lt;&lt;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$@</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span>0; i &lt; <span style="color:#f99b15">${#</span><span style="color:#ef6155">array</span>[*]<span style="color:#f99b15">}</span>; i++ <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[[</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">array</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">==</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">needle</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]]</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$i</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset array needle IFS
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><h3 id="paramètres">Paramètres</h3>
<ul>
<li><code>needle</code> est la valeur à rechercher</li>
<li><code>haystack</code> est le tableau dans lequel chercher</li>
</ul>
<h3 id="valeurs-de-retour">Valeurs de retour</h3>
<ul>
<li>Retourne la clé pour <code>needle</code>, si elle est trouvée dans le tableau <code>haystack</code></li>
<li>Autrement retourne <code>1</code> : considérez cette valeur comme <code>FALSE</code></li>
</ul>
<h2 id="exemple">Exemple</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>declare -a <span style="color:#ef6155">color</span><span style="color:#5bc4bf">=(</span><span style="color:#48b685">&#34;blue&#34;</span>, <span style="color:#48b685">&#34;red&#34;</span>, <span style="color:#48b685">&#34;green&#34;</span>, <span style="color:#48b685">&#34;grey&#34;</span><span style="color:#5bc4bf">)</span>;
</span></span><span style="display:flex;"><span>echo <span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>array_search <span style="color:#48b685">&#34;red&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">color</span>[@]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Fonction array_search() en bash équivalente à celle de PHP]]></summary>
        <published>2017-07-29T18:19:29+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9cea5f4b-adb2-9fcf-aaff-6cd10245b264</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-wan/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accepte de gèrer les connexions sortantes vers WAN</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="WAN" scheme="http://doc.huc.fr.eu.org/fr/tags/wan/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>⇒ Accepter les connexions vers Internet (<abbr title="World Area Network">WAN</abbr>
),
en admettant que votre adresse ip fasse partie de la classe C, segment
réseau de type 192.168.0.0 :</p>
<p><code>iptables -A OUTPUT -o eth0 -s 192.168.0.1 -m conntrack --ctstate ! INVALID -j ACCEPT</code></p>
<hr>
<p>Il peut-être intéressant de la faire suivre de cette règle de 
<a class="inside" href="/fr/sec/firewall/iptables-reject-wan/" title="Lien interne vers l&#39;article : 'iptables rejette les connexions entrantes WAN'">rejet</a>
…</p>
<hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/accept_wan/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour autoriser les connexions sortantes vers WAN avec Iptables]]></summary>
        <published>2017-07-29T14:03:15+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3be6046b-f67e-348f-d08b-bf7793313485</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-reject-wan/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables rejette les connexions entrantes WAN</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="reject" scheme="http://doc.huc.fr.eu.org/fr/tags/reject/" />
        <category term="WAN" scheme="http://doc.huc.fr.eu.org/fr/tags/wan/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>⇒ Si l&rsquo;on est une station, refuser poliment les paquets demandant une connexion
et venant d&rsquo;Internet se dit ainsi :</p>
<p><code>iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.0.1 -m conntrack --ctstate NEW -j REJECT</code></p>
<p>Il peut-être intéressant de la faire précéder de cette règle 
<a class="inside" href="/fr/sec/firewall/iptables-accept-wan/" title="Lien interne vers l&#39;article : 'iptables accepte de gèrer les connexions sortantes vers WAN'">iptables accepte de gèrer les connexions sortantes vers WAN</a>

…</p>
<hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/reject_wan/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour rejeter les connexions entrantes depuis WAN avec Iptables]]></summary>
        <published>2017-07-29T13:42:29+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b0461250-047f-98bd-e4ec-887749715345</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-multiport/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables gère le mode multiport</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="multiport" scheme="http://doc.huc.fr.eu.org/fr/tags/multiport/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>L&rsquo;extension <code>multiport</code> d&rsquo;iptables permet de spécifier une et une seule
règle pour cibler plusieurs services !</p>
<p><code>iptables -A INPUT -i eth0 -p TCP -m multiport --dports 20-22,80,443 -m conntrack --ctstate NEW -j ACCEPT</code></p>
<h2 id="exemples">Exemples</h2>
<p>Au lieu d&rsquo;écrire :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># autorise entree-sortie vers ssh, si est server ssh</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.168.0.0/24 -d 192.168.0.1 -m conntrack --ctstate ! INVALID -p TCP --dport <span style="color:#f99b15">22</span> -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -s 192.168.0.1 -d 192.168.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -p TCP --sport <span style="color:#f99b15">22</span> -j ACCEPT
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># autorise entree-sortie vers DNS &amp;amp;lt;-&amp;amp;gt; LAN, si est server DNS</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.168.0.0/24 -d 192.168.0.1 -m conntrack --ctstate ! INVALID -p TCP --dport <span style="color:#f99b15">53</span> -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -s 192.168.0.1 -d 192.168.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -p TCP --sport <span style="color:#f99b15">53</span> -j ACCEPT
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># autorise entree-sortie vers Cups &amp;amp;lt;-&amp;amp;gt; LAN, si est server Cups</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.168.0.0/24 -d 192.168.0.1 -m conntrack --ctstate ! INVALID -p TCP --dport <span style="color:#f99b15">631</span> -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -s 192.168.0.1 -d 192.168.0.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -p TCP --sport <span style="color:#f99b15">631</span> -j ACCEPT
</span></span></code></pre></div><p>Écrivez donc :</p>
<pre tabindex="0"><code>iptables -A INPUT -i eth0 -s 192.168.0.0/24 -d 192.168.0.1 -p TCP -m multiport --dports 22,53,631 -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A OUTPUT -o eth0 -s 192.168.0.1 -d 192.168.0.0/24 -p TCP -m multiport --sports 22,53,631 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/multiport/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer le mode multiport avec Iptables]]></summary>
        <published>2017-07-29T13:23:41+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:078ae268-c752-9850-ff82-f9feeb4fffc4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-passive-ftp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accepte de gèrer le mode FTP passif</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="FTP" scheme="http://doc.huc.fr.eu.org/fr/tags/ftp/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Les modules <code>ip_conntrack</code>, et <code>ip_conntrack_ftp</code> doivent être chargés !</div>

<pre tabindex="0"><code>iptables -A OUTPUT -o eth0 -p tcp --sport 1024: -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A INPUT -i eth0  -p tcp --dport 1024: -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/ftp_passif/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions en mode FTP passif avec Iptables]]></summary>
        <published>2017-07-29T13:07:00+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8f87d898-2937-0cb7-de4a-97e4da53e993</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-active-ftp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accepte de gèrer le mode FTP actif</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="FTP" scheme="http://doc.huc.fr.eu.org/fr/tags/ftp/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Exemple de règles pour gèrer les connexions en mode FTP actif avec Iptables :</p>
<pre tabindex="0"><code>iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 20,21 -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A INPUT -i eth0  -p tcp -m multiport --dports 20,21 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/ftp_actif/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions en mode FTP actif avec Iptables]]></summary>
        <published>2017-07-29T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a56900b5-6640-70a5-b401-e59f0d89045a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-limit-flood/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables limite le flood</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="limit" scheme="http://doc.huc.fr.eu.org/fr/tags/limit/" />
        <category term="flood" scheme="http://doc.huc.fr.eu.org/fr/tags/flood/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Une des attaques possible est de saturer votre interface réseau par un nombre
conséquent de connexions ou tentatives de connexion dans un espace de temps
très restreint.</p>
<p>Pour éviter de saturer l&rsquo;interface réseau, on utilise une technique limitant
le nombre de connexions au-delà desquelles toute autre tentative sera rejetée.</p>
<p>⇒ TCP Syn flood :</p>
<p><code>iptables -A INPUT -i eth0 -p tcp --syn -m limit --limit 3/s -j ACCEPT</code></p>
<p>⇒ UDP Syn flood :</p>
<p><code>iptables -A INPUT -i eth0 -p udp -m limit --limit 10/s -j ACCEPT</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong> : Certains sites mettent le flag <code>--syn</code> après le protocole <code>udp</code>,
sachez que ce flag n&rsquo;existe pas pour le protocole udp.</div>

<p>⇒ Ping flood  :</p>
<pre tabindex="0"><code>iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
iptables -A INPUT -i eth0 -p icmp --icmp-type echo-reply -m limit --limit 1/s -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/limit_flood/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour limiter le nombre de connexions avec Iptables]]></summary>
        <published>2017-07-29T12:38:55+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:1e12dfe8-2648-c011-c4e5-7e819d38ec1b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-established-related-connections/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accept les connexions établies ou relatives</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="established" scheme="http://doc.huc.fr.eu.org/fr/tags/established/" />
        <category term="related" scheme="http://doc.huc.fr.eu.org/fr/tags/related/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>⇒ Règle simple, juste pour le protocole tcp :</p>
<pre tabindex="0"><code>iptables -A INPUT -i eth0 -d 192.168.0.1 -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -S 192.168.0.1 -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</code></pre><p>⇒ Règle plus évoluée, pour les protocoles icmp, tcp et udp :</p>
<pre tabindex="0"><code>iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate RELATED -j ACCEPT

iptables -A INPUT -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -p icmp -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT

iptables -A OUTPUT -p tcp ! --syn -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m conntrack --ctstate RELATED -j ACCEPT

iptables -A OUTPUT -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p icmp -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/accept_established/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions établies ou relatives avec Iptables]]></summary>
        <published>2017-07-29T12:30:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:be3f4f66-e6b4-72bb-4ac5-ab4db1a4ffb9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/home-chiffre/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : Gestion de connexion avec Home chiffré</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="HOME" scheme="http://doc.huc.fr.eu.org/fr/tags/home/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Eh, oui, lorsqu&rsquo;on utilise des comptes utilisateurs sur un
ordinateur/serveur avec un &ldquo;/home&rdquo; chiffré… Adieu la connexion SSH avec les
clés d&rsquo;authentification !</p>
<p>Mais non… nous allons remédier à la situation.</p>
<h2 id="création-dun-répertoire-hors-home-chiffré">Création d&rsquo;un répertoire hors Home chiffré</h2>
<p>Le plus simple est de créer un répertoire hors votre Home chiffré, tel
que <code>$HOME/.ssh/$USER</code>. Ce dernier peut être absolument ailleurs, tel
que dans <code>/etc/ssh</code>… pourvu qu&rsquo;il soit lisible hors chiffrement du
répertoire Home.</p>
<pre tabindex="0"><code>:# mkdir -p /home/.ssh/USER
:# chown -R USER:USER /home/.ssh/USER
:# chmod 0700 /home/.ssh/USER
</code></pre><p>Bien sûr vous remplacez la mention <code>USER</code> par l&rsquo;identifiant utilisateur
désiré.</p>
<p>Puis vous créez avec vos droits utilisateurs un fichier nommé
<code>authorized_keys</code> où vous copiez votre clé d&rsquo;authentification SSH, de
préférence ED25519.</p>
<p>N&rsquo;oubliez pas de mettre des droits minimum dessus, tel que :</p>
<p><code>$ chmod 0600 /home/.ssh/USER/authorized_keys</code></p>
<h2 id="modification-fichier-sshd_config">Modification fichier sshd_config</h2>
<p>Maintenant, il faut modifier le fichier de configuration du serveur SSH,
à savoir <code>/etc/ssh/sshd_config</code>, pour modifier la ligne
<code>AuthorizedKeysFiles</code> de telle manière :</p>
<p><code># sed -i -e &quot;s#AuthorizedKeysFile     %h/.ssh/authorized_keys#AuthorizedKeysFile      /home/.ssh/%u/authorized_keys#&quot; /etc/ssh/sshd_config</code></p>
<p>Vérifiez les droits d&rsquo;accès et d&rsquo;appartenances utilisateurs !</p>
<p>Ou, par tout autre moyen de votre crû, avec des droits administrateurs,
bien sûr !</p>
<p>Puis, relancez le service ssh ;-)</p>
<p>Et, voilà !</p>
<h2 id="remerciements">Remerciements</h2>
<ul>
<li><a href="https://stephen.rees-carter.net/thought/encrypted-home-directories-ssh-key-authentication" rel="external">source</a></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment configurer SSH pour arriver à se connecter à son répertoire personnel chiffré !]]></summary>
        <published>2017-07-29T11:30:24+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a3ada139-3f0c-6477-49eb-d2684008ba20</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-lo/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accepte tout flux sur l&#39;interface locale</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="lo" scheme="http://doc.huc.fr.eu.org/fr/tags/lo/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Permettre à l&rsquo;interface locale de discuter est important !</strong></p>
<p>⇒ Autorise la connexion sur l&rsquo;interface locale :</p>
<pre tabindex="0"><code>iptables -A INPUT -i lo -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -o lo -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
</code></pre><p>⇒ règle simpliste :</p>
<pre tabindex="0"><code>iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/accept_lo/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour autoriser le flux sur l&#39;interface locale avec Iptables]]></summary>
        <published>2017-07-29T12:19:32+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9b1d0964-93da-9c83-5261-5f6eb7b4bf96</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-drop-null-xmas-scan/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables refuse les scans NULL et XMAS</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="drop" scheme="http://doc.huc.fr.eu.org/fr/tags/drop/" />
        <category term="scan" scheme="http://doc.huc.fr.eu.org/fr/tags/scan/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Il existe un type de scan de port, dit XMAS et NULL ; pour s&rsquo;en protéger :</p>
<pre tabindex="0"><code>iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/drop_xmas_nullscan/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour refuser les scans nommés NULL, XMAS avec Iptables]]></summary>
        <published>2017-07-29T12:01:48+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:cb5826fc-6e7b-f4ed-52a5-2569a5941d31</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-ping/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accepte de gèrer le ping</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="ping" scheme="http://doc.huc.fr.eu.org/fr/tags/ping/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>⇒ Règle simpliste :</p>
<pre tabindex="0"><code>iptables -A OUTPUT -o eth0 -p icmp -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A INPUT -i eth0 -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
</code></pre><p>⇒ Règles plus fines :</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION :</strong>
Remplacez la mention <strong>adr_ip_gw</strong> par l&rsquo;adresse ip de votre routeur/passerelle… <br>
celle-ci est précisée comme source ou destination parce que ce type d&rsquo;ICMP
ne doit être envoyé ou reçu que de votre passerelle.</div>

<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type0 -m conntrack --ctstate ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Echo reply&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type3/0  -m conntrack --ctstate RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Destination Net Unreachable&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type3/1  -m conntrack --ctstate RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Destination Host Unreachable&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type8  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Echo mssg&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -s adr_ip_gw -p icmp -m icmp --icmp-type9 -m conntrack --ctstate RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Router Advert&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -s adr_ip_gw -p icmp -m icmp --icmp-type10 -m conntrack --ctstate NEW -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Router Select&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type11  -m conntrack --ctstate RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Time exceeded&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type12  -m conntrack --ctstate RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Param pb&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type13  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Timestamp mssg&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type14  -m conntrack --ctstate ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Timestamp reply&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type17  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Addr Mask mssg&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -s adr_ip_gw -p icmp -m icmp --icmp-type18  -m conntrack --ctstate ESTABLISHED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Addr Mask reply&#34;</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -m icmp --icmp-type30  -m conntrack --ctstate NEW,RELATED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Traceroute&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type0 -m conntrack --ctstate ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type3/0 -m conntrack --ctstate RELATED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type3/1 -m conntrack --ctstate RELATED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type8 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -d adr_ip_gw -p icmp -m icmp --icmp-type9 -m conntrack --ctstate RELATED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -d adr_ip_gw -p icmp -m icmp --icmp-type10 -m conntrack --ctstate NEW -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type11 -m conntrack --ctstate RELATED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type12 -m conntrack --ctstate RELATED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type13 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type14 -m conntrack --ctstate ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type17 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -d adr_ip_gw -p icmp -m icmp --icmp-type18 -m conntrack --ctstate ESTABLISHED -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -m icmp --icmp-type30 -m conntrack --ctstate NEW,RELATED -j ACCEPT
</span></span></code></pre></div><hr>
<p><strong>Je vous invite très fortement à lire ATTENTIVEMENT sur le filtrage d&rsquo;ICMP
sous Linux : 
<a class="inside" href="/fr/sec/firewall/linux-firewall-icmp/" title="Lien interne vers l&#39;article : 'Linux : firewall ICMP'">Linux : firewall ICMP</a>

</strong></p>
<hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/ping/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer le ping avec Iptables]]></summary>
        <published>2017-07-29T11:56:01+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d2318f52-da01-f51f-7bca-a413842d759f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-drop-bogons/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables refuse les réseaux Bogons</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="drop" scheme="http://doc.huc.fr.eu.org/fr/tags/drop/" />
        <category term="Bogons" scheme="http://doc.huc.fr.eu.org/fr/tags/bogons/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La <strong>RFC 1918</strong> nous fait comprendre que les adresses de type privé ne doivent
pas être publié sur Internet. De fait, puisque nul ne doit contacter l&rsquo;interface
réseau internet, il est bon de dropper tout flux qui y correspond !</p>
<p>La <strong>RFC 5735</strong> définit l&rsquo;ensemble des réseaux dits spécifiques, qu&rsquo;il est
bon de ne pas retrouver sur Internet !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 0.0.0.0/8 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP <span style="color:#776e71"># adr Class A privee</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 100.64.0.0/10 -j DROP <span style="color:#776e71"># définit par la RFC 6598</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP <span style="color:#776e71"># adr de Loopback</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 169.254.0.0/16 -j DROP  <span style="color:#776e71"># adr Link Local Network</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP <span style="color:#776e71"># adr Class B privee</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.0.0.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.0.2.0/24 -j DROP <span style="color:#776e71"># adr TEST-NET</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.88.99.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP <span style="color:#776e71"># adr Class C Privee</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 198.18.0.0/15 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 198.51.100.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 203.0.113.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 224.0.0.1/4 -j DROP <span style="color:#776e71"># adr Class D MultiCast</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 240.0.0.0/4 -j DROP <span style="color:#776e71"># adr Class E Reservee</span>
</span></span><span style="display:flex;"><span>iptables -A INPUT -i eth0 -s 255.255.255.255 -j DROP <span style="color:#776e71"># aucun flux ne doit être de source avec l&#39;adressage de loopbak...</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 0.0.0.0/8 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 10.0.0.0/8 -j DROP <span style="color:#776e71"># adr Class A privee</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 100.64.0.0/10 -j DROP <span style="color:#776e71"># définit par la RFC 6598</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 127.0.0.0/8 -j DROP <span style="color:#776e71"># adr de Loopback</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 169.254.0.0/16 -j DROP  <span style="color:#776e71"># adr Link Local Network</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 172.16.0.0/12 -j DROP <span style="color:#776e71"># adr Class B privee</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 192.0.0.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 192.0.2.0/24 -j DROP <span style="color:#776e71"># adr TEST-NET</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 192.88.99.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 192.168.0.0/16 -j DROP <span style="color:#776e71"># adr Class C Privee</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 198.18.0.0/15 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 198.51.100.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 203.0.113.0/24 -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 224.0.0.1/4 -j DROP <span style="color:#776e71"># adr Class D MultiCast</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 240.0.0.0/4 -j DROP <span style="color:#776e71"># adr Class E Reservee</span>
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -o eth0 -d 255.255.255.255 ! -p icmp -j DROP <span style="color:#776e71"># aucun flux ne doit être à destination avec l&#39;adressage de loopbak, sauf sur le protocole ICMP...</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Pensez à supprimer la ligne correspondant à votre réseau !</div>

<h2 id="documentations">Documentations</h2>
<ul>
<li><a href="https://www.rfc-editor.org/info/rfc1918" title="RFC Editor : Information à-propos de la RFC 1918">RFC 1918</a>
, <a href="https://www.rfc-editor.org/info/rfc5735" title="RFC Editor : Information à-propos de la RFC 5735">RFC 5735</a>
</li>
</ul>
<hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/drop_private2public/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour refuser les réseaux Bogons avec Iptables]]></summary>
        <published>2017-07-29T11:49:33+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:5fa442df-5363-4be3-6b34-cc6428c10649</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/perishablepress-6g/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PerishablePress 6G pour nginx</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <category term="PerishablePress" scheme="http://doc.huc.fr.eu.org/fr/tags/perishablepress/" />
        <category term="6G" scheme="http://doc.huc.fr.eu.org/fr/tags/6g/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Le projet <strong><a href="https://perishablepress.com/6g" rel="external">Perishable Press 6G</a></strong> est un projet de règles de filtrage
pour le serveur Apache, version 2 de préférence, à utiliser dans le
fichier <code>.htaccess</code>.</p>
<p>Personnellement, j&rsquo;avoue préférer nginx.</p>
<p>Je rappelle que les règles .htaccess n&rsquo;existent pas pour nginx, même si
on peut recréer le principe, de manière différente !</p>
<p>Donc, j&rsquo;ai eu l&rsquo;idée de convertir ces règles de filtrage et autres blacklistages
pour l&rsquo;intégrer à l&rsquo;usage que j&rsquo;ai de nginx.</p>
<p>À moins que je ne me trompe, cela devrait donner ce qui suit ci-dessous :</p>
<h2 id="configuration">Configuration</h2>
<h3 id="6gquery-strings">6G:[QUERY STRINGS]</h3>
<p>Dans le fichier de configuration du domaine à gérer, contexte <code>server</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#776e71"># 6G Perishable Press: Queries String
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># @ https://perishablepress.com/6g/
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(eval\()&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(127\.0\.0\.1)&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">([a-z0-9]{2000})&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(javascript\:)(.*)(\</span>;<span style="color:#815ba4">)&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(base64_encode)(.*)(\()&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(GLOBALS|REQUEST)(=|\[|%)&amp;quot</span>;  <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(&amp;lt</span>;<span style="color:#815ba4">|%3C).*script.*(&amp;gt</span>;<span style="color:#815ba4">|%3)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(\|\.\.\.|\.\./|~|`|&amp;lt</span>;<span style="color:#815ba4">|&amp;gt</span>;<span style="color:#815ba4">|\|)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(boot\.ini|etc/passwd|self/environ)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(thumbs?(_editor|open)?|tim(thumb)?)\.php&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(\&#39;|\&amp;quot</span>;<span style="color:#815ba4">)(.*)(drop|insert|md5|select|union)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span></code></pre></div><h4 id="wordpress-plugin-timthumb">WordPress: plugin TimThumb</h4>
<p>Si jamais vous utilisez le plugin TimTumb, il vous faudra commenter la ligne
suivante :</p>
<p><code>location ~* &amp;quot;(thumbs?(_editor|open)?|tim(thumb)?)\.php&amp;quot; { return 444; }</code></p>
<h3 id="6grequest-method">6G:[REQUEST METHOD]</h3>
<p>Toujours dans le contexte <code>server</code>, utilisons la capacité native de nginx,
si la connexion n&rsquo;est pas de type GET, ou HEAD, alors bloquons le flux :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$request_method</span> <span style="color:#48b685">!~</span> <span style="color:#48b685">^(GET|HEAD)</span>$ <span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><h3 id="nuage-informatique">Nuage informatique</h3>
<p>Pour ceux qui utilisent un serveur de nuage informatique, tel que Nextcloud,
ajoutez au moins la méthode <code>PUT</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$request_method</span> <span style="color:#48b685">!~</span> <span style="color:#48b685">^(GET|HEAD|PUT)</span>$ <span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><h3 id="formulaires">Formulaires</h3>
<p>Si vous avez dans votre site, des pages qui ont des formulaires qui envoient
les données par la requête POST, ajoutez la dans la déclaration ci-dessus,
tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$request_method</span> <span style="color:#48b685">!~</span> <span style="color:#48b685">^(GET|HEAD|POST)</span>$ <span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><h3 id="6greferrers">6G:[REFERRERS]</h3>
<p>Pour ce filtrage, utilisons la déclaration <code>map</code>, dans le contexte <code>http</code>
du serveur :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#776e71"># @ https://perishablepress.com/6g/
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_referer</span> <span style="color:#ef6155">$bad_referer</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~*\{.*\:</span> <span style="color:#f99b15">1</span>; <span style="color:#776e71"># ShellShock
</span></span></span><span style="display:flex;"><span>    <span style="color:#776e71">#~([a-z0-9]{2000}) 1;
</span></span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~(?i)(semalt.com|todaperfeita)</span> <span style="color:#f99b15">1</span>;
</span></span></code></pre></div><p>La règle <code>~([a-z0-9]{2000}) 1;</code>  est mis en commentaire - je n&rsquo;ai pas encore
trouvé comment faire pour l&rsquo;inclure sans retour d&rsquo;erreur !</p>
<p>Puis, rajouter dans le contexte <code>server</code> ladite déclaration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$bad_referer</span><span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><h3 id="6grequest-strings">6G:[REQUEST STRINGS]</h3>
<p>Les filtres sur les requêtes sont toutes aussi simples que celles sur les
<a href="/fr/web/nginx/perishablepress-6g/#6gquery-strings">queries</a>… de type <code>location</code>, dans le contexte <code>server</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#776e71"># 6G Perishable Press : Request String
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># @ https://perishablepress.com/6g/
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(https?|ftp|php):/&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(=\\&#39;|=\%27|/\\&#39;/?)\.&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">/(\$(\&amp;amp</span>;<span style="color:#815ba4">)?|\*|\&amp;quot</span>;<span style="color:#815ba4">|\.|,|&amp;amp</span>;<span style="color:#815ba4">|&amp;amp</span>;<span style="color:#815ba4">amp</span>;<span style="color:#815ba4">?)/?$&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(\{0\}|\(/\(|\.\.\.|\+\+\+|\\&amp;quot</span>;<span style="color:#815ba4">\\&amp;quot</span>;<span style="color:#815ba4">)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(~|`|&amp;lt</span>;<span style="color:#815ba4">|&amp;gt</span>;<span style="color:#815ba4">|:|</span>;<span style="color:#815ba4">|,|%|\|\s|\{|\}|\[|\]|\|)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">/(=|\$&amp;amp</span>;<span style="color:#815ba4">|_mm|(wp-)?config\.|cgi-|etc/passwd|muieblack)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">(&amp;amp</span>;<span style="color:#815ba4">pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf)$&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">/(^$|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span></code></pre></div><h4 id="cgi">CGI</h4>
<p>Pour ceux qui utilisent un service CGI, supprimez la mention <code>cgi-|</code> de la
ligne suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&amp;quot</span>;<span style="color:#815ba4">/(=|\$&amp;amp</span>;<span style="color:#815ba4">|_mm|(wp-)?config\.|cgi-|etc/passwd|muieblack)&amp;quot</span>; <span style="color:#815ba4">{</span> <span style="color:#48b685">return</span> <span style="color:#f99b15">444</span>; <span style="color:#815ba4">}</span>
</span></span></code></pre></div><h3 id="6guser-agents">6G:[USER AGENTS]</h3>
<p>Là encore, utilisons l&rsquo;astuce de la déclaration <code>map</code>, dans le contexte <code>http</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#776e71"># @ https://perishablepress.com/6g/
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_user_agent</span> <span style="color:#ef6155">$bad_bot</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~*\{.*\:</span> <span style="color:#f99b15">1</span>; <span style="color:#776e71"># ShellShock
</span></span></span><span style="display:flex;"><span>    <span style="color:#776e71">#~(?i)([a-z0-9]{2000}) 1;
</span></span></span><span style="display:flex;"><span>   <span style="color:#5bc4bf">~(?i)(archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune)</span> <span style="color:#f99b15">2</span>;
</span></span></code></pre></div><p>Puis écrivons dans le contexte <code>server</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$bad_bot</span><span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><hr>
<p>Et, voilà !</p>
<p>PS : Pensez à redémarrer le serveur nginx, après avoir lancé le test de la config !</p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment paramétrer les règles de blocage d&#39;adresses IP du projet &#39;Perishable Press 6G&#39; avec nginx]]></summary>
        <published>2017-07-29T10:52:11+02:00</published>
        <updated>2025-11-13T14:12:52+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4d5fd503-fab1-c891-ff2a-1bb2780478eb</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-ip-forward/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables partage la connexion internet</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="forward" scheme="http://doc.huc.fr.eu.org/fr/tags/forward/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">À utiliser pour une machine faisant office de passerelle…</div>

<p>Partager une connexion sous linux est assez simple…</p>
<p>⇒ Dans un premier temps, il faut autoriser la redirection d&rsquo;IP, avec des
droits administrateur :</p>
<p><code># echo 1 &gt; /proc/sys/net/ipv4/ip_forward</code></p>
<p>⇒ Ensuite autoriser la redirection avec iptables</p>
<ul>
<li>
<p>Avec une adresse ip extérieur statique : <br>
<code>iptables -t nat -A POSTROUTING -o eth1  -j SNAT --to 1.2.3.4</code> <br>
où  l&rsquo;adresse IP <code>1.2.3.4</code> est à remplacer par votre réelle adresse IP
extèrieure.</p>
</li>
<li>
<p>Avec une adresse ip extérieur dynamique : <br>
<code>iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE</code></p>
</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>⇒ Ajouter à votre fichier <code>/etc/sysctl.conf</code> :</p>
<p><code>net.ipv4.ip_forward=1</code></p>
<h2 id="exemples">Exemples</h2>
<pre tabindex="0"><code>iptables -A FORWARD -i eth0 -o ppp0 -s 192.168.0.0/24 -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A FORWARD -i ppp0 -o eth0 -d 192.168.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/partage_connexion/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour partager une connexion vers Internet avec Iptables]]></summary>
        <published>2017-07-28T16:09:39+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:83b3cbbd-cecc-79cf-c2bd-ceb8ba9afff8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/connaitre-protocole-ssh/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : Mieux Connaître le Protocole SSH</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <content type="html"><![CDATA[<h2 id="installation-dopenssh">Installation d&rsquo;OpenSSH</h2>
<h3 id="debian--buntu">Debian &amp; *Buntu</h3>
<p>Sur une Debian GNU/Linux, ou une *Buntu, et autre dérivées :
<code>apt install ssh</code>…</p>
<p>Quelle que soit la distribution Linux utilisé, le fichier de
configuration se trouve être <code>/etc/ssh/sshd_config*</code>.</p>
<h3 id="openbsd">OpenBSD</h3>
<p>Sur OpenBSD, c&rsquo;est installé dans le système de base !</p>
<h2 id="utilisation-de-ssh">Utilisation de SSH</h2>
<p>SSH est très facile à utiliser :</p>
<h3 id="connexion-à-distance-vers-le-serveur">Connexion à distance vers le serveur</h3>
<p><code>ssh server.domaine.com</code> ou <code>ssh adresse_ip</code> est la méthode de base.</p>
<p>Dans ce cas, si la connexion se fait, il vous sera demandé votre nom
d&rsquo;utilisateur sur ce serveur, et le mot de passe correspondant.</p>
<p><code>ssh votre_nom_user@server.domaine.com</code> ou
<code>ssh -l votre_nom_user server.domaine.com</code> est la manière de spécifier
explicitement votre nom d&rsquo;utilisateur.</p>
<p>Dans ce cas, dès la connexion établie, il ne vous sera demandé plus que
le mot de passe correspondant à votre identifiant utilisateur.</p>
<h3 id="exécution-de-commandes-à-distance">Exécution de commandes à distance</h3>
<p>Il suffit d&rsquo;établir une connexion avec la commande à lancer : <br>
<code>ssh votre_nom_user@server.domaine.com date</code></p>
<p>Précisément, cette commande interroge le serveur pour connaître ses date
et heure.</p>
<h3 id="copie-de-fichier-à-distance">Copie de fichier à distance</h3>
<p>C&rsquo;est la commande <code>scp</code>, tout autant sécurisée, qui le permet aussi
simplement.</p>
<p><code>scp monfichier votre_nom_user@server.domaine.com:/~/</code> enverra le
fichier dans votre répertoire personnel sur le serveur en question.</p>
<p><code>scp votre_nom_user@server.domaine.com:/~/monfichier monfichier</code> ira
chercher sur le serveur votre fichier et le déposera dans votre
répertoire en cours.</p>
<p>Pour faire une copie récursive d&rsquo;un répertoire :
<code>ssh -r /votre_rep votre_nom_user@server.domaine.com:/~/</code></p>
<h3 id="transfert-ftp">Transfert ftp</h3>
<p>Le transfert de fichiers par ftp, de manière sécurisée, est aussi
possible…</p>
<p>Utilisez la commande suivante : <code>sftp votre_nom_user@server.domaine.com</code></p>
<p>Certains clients FTP graphique acceptent ce mode de connexion, il suffit
de choisir le mode de connexion <strong>sftp over SSH2</strong>.</p>
<h2 id="authentification-sécurisée-par-ssh">Authentification sécurisée par SSH</h2>
<h3 id="configuration-du-service">Configuration du service</h3>
<p>OpenSSH permet des méthodes diverses d&rsquo;authentification, et ce en
fonction de la politique de sécurité privilégiée.</p>
<ul>
<li>Une des premières choses à faire est d&rsquo;interdire l&rsquo;accès au compte root, afin de ne pas &ldquo;tenter le diable&rdquo; : <br> Il faut donc modifier la ligne <code>PermitRootLogin</code> en lui donnant la valeur <strong>no</strong>.</li>
<li>Forcer la sécurité sur la deuxième version du protocole est à envisager sérieusement ; <br> par la modification de la ligne <strong>Protocol</strong> en lui donnant la valeur <code>2</code> <em>(version de protocole plus sécurisée)</em></li>
<li>Créer l&rsquo;authentification par mot de passe, et interdire les mots de passe vides. <br> Donc s&rsquo;assurer que la ligne <code>PasswdAuthentication</code> soit à <code>yes</code> et que <code>PermitEmptypasswords</code> soit à <code>no</code>.</li>
<li>Encourager l&rsquo;authentification par clé publique est à promouvoir ; car une clé appartient à un utilisateur et un seul&hellip; <br> Cela signifie positionner la ligne <code>PubkeyAuthentication</code> à <code>yes</code> et supprimer le symbole dièze devant la ligne <code>AutorizedKeysFile</code>.</li>
<li>Pour finir par supprimer les protocoles moins sécurisés : <br> ce qui signifie d&rsquo;imposer aux lignes <code>RSAAuthentication</code>, <code>RhostsAuthentication</code>, <code>RhostsRSAAuthentication</code> et <code>HostbasedAuthentication</code> la valeur <code>no</code> et d&rsquo;ignorer <code>IgnoreRhosts</code> par <code>yes</code>, si elles sont présentes dans le fichier !</li>
<li>Pour information, il est possible de manière rudimentaire et exclusive de spécifier les autorisations uniquement à certains utilisateurs ou à un groupe d&rsquo;utilisateurs. <br> On se servira pour cela des directives <code>AllowUsers</code> et <code>AllowGroups</code> que l&rsquo;on ajoutera au fichier de configuration.</li>
</ul>
<p>Une fois le fichier <code>sshd_config</code> modifié, pensez donc à
(re)démarrer le service : <br>
<code>/etc/init.d/sshd restart</code> ou <code>service ssh restart</code></p>
<h3 id="usage-de-clé-publique">Usage de clé publique</h3>
<p>L&rsquo;usage de clé publique ayant été notifié dans le fichier de
configuration et aux utilisateurs,il est possible de les créer par la
commande suivante <code>ssh-keygen</code>.</p>
<ul>
<li><code>ssh-keygen -t rsa -b 2048</code></li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>ATTENTION : Il est recommandé les deux choses suivantes :</p>
<ul>
<li><span class="red">ne pas générer des clés plus petites que 2048 bits</span>
, <strong>préférez</strong> une valeur de
<strong>4096 bits</strong> ;</li>
<li>de même, <span class="red">les protocoles de chiffrement <strong>DSA</strong> et
<strong>ECDSA</strong> ne doivent plus être utilisés</span>
… <strong>utilisez RSA</strong> ou au mieux un protocole de chiffrement à courbes elliptiques, tel ed25519 !</li>
</ul>
<p>Pour plus d&rsquo;informations, veuillez lire mon autre <a class="inside" href="/fr/sec/ssh/configuration-securisee/" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">article</a></p>
</div>

<p>Lors de la génération de celle-ci, il vous sera demandé de taper une
passphrase que vous choisirez consciencieusement.</p>
<p>Dans un cas, comme dans l&rsquo;autre, cela crée une clé privée et une clé
publique dans votre répertoire personnel <code>$HOME/.ssh/</code> ; <br> pour les
clés RSA, ce sont les fichiers <strong>id_rsa</strong> et <strong>id_rsa.pub</strong>,
et réciproquement pour les autres clés.</p>
<p><span em>Veillez à ne jamais fournir la clé privée, et ce sous aucun
prétexte. Votre sécurité en dépend fortement !</span></p>
<p>Une fois, vos clés générées, copiez votre clé publique sur le serveur : <br>
<code>scp -p $HOME/.ssh/id_rsa.pub votre_nom_user@server.domaine.com:/~/.ssh/authorized_keys</code></p>
<p>Ensuite on va garder en mémoire la passphrase dans notre ordinateur afin
de ne pas être obligé de la taper à chaque fois : <br>
<code>eval ssh-agent ssh-add</code> <br>
Pour la dernière fois, il va vous être demandé de taper votre passphrase, faites-le.</p>
<p>Lors de vos prochaines connexions en SSH sur le serveur, il ne vous
restera plus… qu&rsquo;à travailler !</p>
<h3 id="création-de-tunnel">Création de Tunnel</h3>
<p>Pour créer un tunnel de connexion ssh, qui permette d&rsquo;encapsuler
d&rsquo;autres protocoles, il vous faut vous l&rsquo;écrire ainsi : <br>
<code>ssh -L numero_port_encapsulé:adresse_ip_local:numero_port_routé adresse_ip_server</code></p>
<ul>
<li>L&rsquo;option <code>-L</code> indique l&rsquo;exécution locale,</li>
<li>L&rsquo;option <code>-R</code> indique l&rsquo;exécution à distance.</li>
</ul>
<h3 id="tunnel-x">Tunnel X</h3>
<p>Pour créer un tunnel graphique X-Windows, il faut d&rsquo;abord vérifier que
l&rsquo;option <code>X11 Forwarding</code> soit à <code>yes</code> dans le fichier
<code>/etc/ssh/sshd_config</code>.</p>
<p>Cela étant fait, il ne vous reste plus qu&rsquo;à vous connecter à votre hote
distant : <br> <code>ssh -X nom_machine.nom_domaine.tld</code></p>
<p>Il est possible de lancer en même temps une application : <br>
<code>ssh -X nom_machine.nom_domaine.tld nom_logiciel &amp;</code></p>
<hr>
<p>Ce mémo a été écrit la première fois, par mes soins, sur mon autre site
&ldquo;<a href="https://memoire-grise-liberee.fr.eu.org/Linux/securite/ssh/" rel="external">Mémoire Grise
Libérée</a>&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Apprendre ce qu&#39;est SSH : son protocole, son usage correct au quotidien, ses particularités.]]></summary>
        <published>2017-07-28T14:59:05+01:00</published>
        <updated>2020-02-19T15:51:05+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e1c400a8-9848-396e-5501-63f5265f383f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/iptables-accept-lan/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: iptables accept le trafic interne au LAN</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <category term="accept" scheme="http://doc.huc.fr.eu.org/fr/tags/accept/" />
        <category term="LAN" scheme="http://doc.huc.fr.eu.org/fr/tags/lan/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>⇒ Demander à iptables d&rsquo;accepter tout le trafic de votre ip vers votre lan,
en admettant que vos machines soient sur un réseau de classe C, dont le
segment est 192.168.0.0 :</p>
<pre tabindex="0"><code>iptables -A OUTPUT -o eth0 -s 192.168.0.1 -d 192.168.0.0 / 24 -m conntrack --ctstate ! INVALID -j ACCEPT
iptables -A INPUT  -i eth0 -s 192.168.0.0 / 24 -d 192.168.0.1 -m conntrack --ctstate ! INVALID -j ACCEPT
</code></pre><p>⇒ Accepter le flux de type broadcast :</p>
<pre tabindex="0"><code>iptables -A OUTPUT -o eth0 -s 192.168.0.1  -d 192.168.0.255 -m conntrack --ctstate ! INVALID  -j ACCEPT
iptables -A INPUT  -i eth0 -s 192.168.0.255 -d 192.168.0.1  -m conntrack --ctstate ! INVALID  -j ACCEPT
</code></pre><p>⇒ Accepter le flux BootDHCP vers LAN :</p>
<pre tabindex="0"><code>iptables -A INPUT  -i eth0 -p udp --sport bootpc --dport bootps -m conntrack --ctstate NEW -j ACCEPT
</code></pre><hr>
<p><em>J&rsquo;ai écrit ce mémo, pour la première fois, sur mon autre site : &ldquo;<a href="http://memoire-grise-liberee.fr.eu.org/Linux/IpTables/FAQ/accept_ip2lan/" rel="external">Mémoire Grise Libérée</a>&rdquo;.</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Exemple de règles pour gèrer les connexions venant seulement des autres machines sur le LAN avec Iptables]]></summary>
        <published>2017-07-28T15:22:49+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9d276ad6-f368-a23f-580a-21cd647226b6</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/linux/durcir-kernel-modules/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Durcir Linux : désactiver les modules noyau</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="noyau" scheme="http://doc.huc.fr.eu.org/fr/tags/noyau/" />
        <category term="modules" scheme="http://doc.huc.fr.eu.org/fr/tags/modules/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou, comment titrer : <strong>Améliorons l&rsquo;intégrité du noyau en désactivant la gestion des modules !</strong></p>
<p>En effet, pour améliorer l&rsquo;intégrité du noyau, il est possible, même recommandé,
de désactiver la gestion des modules ; cela a pour propos d&rsquo;empêcher que
quiconque ayant un accès machine puisse charger un module indésirable.</p>
<h2 id="configuration">Configuration</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Gardez à l&rsquo;esprit que si vous désactivez la gestion des modules,
cela risque de vous poser des problèmes de gestion matérielle sur une station… <br>
<em>Exemple : impossible d&rsquo;utiliser des périphériques USB.</em></p>
<p>Préférez utiliser cela sur un serveur.</p>
<p><span class="red">Vous êtes prévenus !</span></p>
</div>

<h3 id="sysctl">sysctl</h3>
<p>Le sous-système <code>sysctl</code> nous permet d&rsquo;activer ou de désactiver la gestion
des modules par la variable <code>kernel.modules_disabled</code>.</p>
<ul>
<li>Une valeur à <code>0</code> permet la gestion des modules,</li>
<li>tandis qu&rsquo;une valeur à <code>1</code> désactive la gestion des modules !</li>
</ul>
<p>De même, il est possible, bien-sûr, de le gérer à-partir du fichier <code>/etc/sysctl.conf</code>.</p>
<h3 id="mise-en-garde">Mise en garde</h3>
<p>Votre système d&rsquo;exploitation fonctionnera, certes, mais seulement en partie ! <br>
<em>Bref, il faut avouer : c&rsquo;est assez ennuyeux, voire ennuyant</em>…</p>
<p><strong>L&rsquo;astuce</strong> est de configurer le fichier <code>/etc/rc.local</code> - <em>qui est appelé
en dernier au chargement du système, du moins sur Debian et *Buntu</em> - en
incluant la commande suivante :</p>
<p><code>sysctl -w kernel.modules_disabled=1</code></p>
<p>mais de laisser la valeur de cette variable à <code>0</code> dans le fichier de configuration
de sysctl !</p>
<p>Ainsi le système au démarrage chargera tous les modules nécessaires à son
bon fonctionnement, et ensuite, interdira tout autre chargement de modules
non autorisé !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment sécuriser sa distribution GNU/Linux en modifiant le noyau Linux]]></summary>
        <published>2017-07-28T14:23:43+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:325d54b8-ae17-1466-0afd-1a7789b90b82</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/linux/durcir-partitionnement/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Durcir Linux : modifier le partitionnement</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="partition" scheme="http://doc.huc.fr.eu.org/fr/tags/partition/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Tout bon linuxien sait que le partitionnement système se gère à partir du
fichier <code>/etc/fstab</code>…</p>
<hr>
<p>Modifions la configuration par défaut, qui utilise le drapeau <code>defaults</code>
concernant l&rsquo;option de montage, pour être plus restrictif… <br>
<em>ce qui aura pour avantage de compliquer la vie si jamais votre station ou
serveur étaient infectés !</em></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Toutes ces modifications sont des modifications système, donc, sont à exécuter
avec des droits administrateurs !</div>

<h2 id="configuration">Configuration</h2>
<h3 id="boot-opt-usr">/boot, /opt, /usr</h3>
<p>Concernant le partitionnement lié à <code>/boot</code>, <code>/opt</code>, <code>/usr</code>, il est
intéressant de les monter en lecture seule et d&rsquo;interdire les fichiers
périphériques nommés <span lang="en">device</span>, pour un serveur -
<em>sur une station, cela posera des difficultés ergonomiques indéniables</em>.</p>
<p>Ce qui donnerait à minima :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">97aabf8d-fa78-4176-b681-888370fbc186  /boot   ext4    defaults,nodev,ro   0   2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">20c0ddea-2db4-4ee5-982f-71b8df26c2fb /opt            ext4    defaults,nodev,ro        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">d84f16a8-d107-49d7-992d-bd9e78488ffd  /usr    ext4    defaults,nodev,ro   0   2</span>
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Étant donné ce que signifie la valeur <code>defaults</code>, soit <code>rw,suid,dev,exec,auto,nouser,async</code>,
on peut donc écrire les options <code>defaults,nodev,ro</code> par <code>async,auto,exec,nodev,nouser,ro,suid</code> !</div>

<h4 id="mise-en-garde-pour-boot-opt-usr">Mise en garde pour /boot, /opt, /usr</h4>
<ul>
<li>Mettre l&rsquo;accès en lecture <code>ro</code> sur les partitionnements <code>/boot</code> et sur <code>/usr</code>
posent quelques petits soucis.</li>
<li>Quant à <code>/opt</code>, pour les rares fois, où c&rsquo;est vraiment nécessaire, on
verra plus bas <a href="/fr/sec/linux/durcir-partitionnement/#remonter-une-partition">comment permettre l&rsquo;écriture</a>,
si besoin.</li>
</ul>
<hr>
<ul>
<li>
<p>⇒ <code>/boot</code> : besoin d&rsquo;un accès en écriture, lors du démarrage, pour l&rsquo;environnement
lié à grub, et surtout du binaire <code>grub-editenv</code>… qui ne peut écrire
de fait ; résultat, il faut réécrire le fichier <code>/etc/fstab</code> avec
l&rsquo;option <code>rw</code>. <br>
Ouvrez le fichier <code>/etc/rc.local</code> - <em>du moins, pour Debian, *Buntu,
et assimilés</em> - et écrivez dedans : <br>
<code>mount -f -o remount,ro /boot</code></p>
</li>
<li>
<p>⇒ <code>/usr</code> : besoin d&rsquo;un accès en écriture, lors de mises-à-jour système,
principalement. Vous aurez le droit à la complainte suivante lors de
l&rsquo;exécution de l&rsquo;invocation <em>post</em> du gestionnaire de paquets <em>(<strong>apt</strong>,
<strong>dpkg</strong>, etc.)</em> : \</p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>mount: /usr: point de montage actif.
</span></span><span style="display:flex;"><span>E: Problem executing scripts DPkg::Post-Invoke <span style="color:#48b685">&#39;mount -o remount,ro /usr&#39;</span>
</span></span><span style="display:flex;"><span>E: Sub-process returned an error code
</span></span></code></pre></div><pre><code>Ce n'est absolument rien de grave ; il vous avertit juste qu'il n'est
pas capable de remonter `/usr` en lecture seule. À vous de voir si vous
voulez vraiment mettre `/usr` en lecture seule, et que ce message d'erreur
ne vous ennuie pas ; pour ne pas être embetter, mieux vaut laisser en `rw`.
</code></pre>
<hr>
<p>Pour résoudre les problèmes ci-dessus, soit vous éditez le fichier <code>/etc/apt/apt.conf</code> -
<em>s&rsquo;il existe</em> - soit vous créez un fichier, tel que <code>/etc/apt/apt.conf.d/00apt</code>,
et écrivez le code suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Pre-Invoke {&#34;mount -o remount,rw /boot&#34;;&#34;mount -o remount,rw /opt&#34;};</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Post-Invoke {&#34;mount -o remount,ro /boot&#34;;&#34;mount -o remount,ro /opt&#34;};</span>
</span></span></code></pre></div><p>Ainsi les gestionnaires <strong>apt</strong>, <strong>dpkg</strong> doivent remonter les partitionnements
en question en écriture avant de faire la mise-à-jour système, et de le
remettre en lecture seulement, après…</p>
<h4 id="informations-anssi-pour-boot-opt-usr">Informations ANSSI pour /boot, /opt, /usr</h4>
<p>Pour info, la documentation de l&rsquo;ANSSI en Octobre 2015, à-propos de
<a href="http://www.ssi.gouv.fr/uploads/2015/10/NP_Linux_Configuration.pdf" rel="external">configurer Linux de manière sécurisée</a>,
informe que :</p>
<ul>
<li><code>/boot</code> devrait avoir les options <code>nosuid,nodev,noexec</code> - <em>il est même
recommandé l&rsquo;usage de l&rsquo;option <code>noauto</code> de manière optionnelle, car
cela sous-tend qu&rsquo;il faut comprendre les incidences et la gestion
générée d&rsquo;ajouter cette dernière option !</em></li>
<li><code>/opt</code> devrait avoir au moins les options <code>nosuid,nodev</code></li>
<li><code>/usr</code> devrait avoir l&rsquo;option, à minima, <code>nodev</code></li>
</ul>
<h4 id="incompatibilités-logicielles-connues">Incompatibilités logicielles connues</h4>
<p>Il peut arriver que certains logiciels refusent de fonctionner. Réflexe :
exécutez-le depuis un terminal, et vérifiez son chemin d&rsquo;exécution.</p>
<ul>
<li><code>/opt</code> : <strong>google-chrome</strong> nécessite pour sa sandbox l&rsquo;usage de l&rsquo;option <code>suid</code>.</li>
</ul>
<h3 id="tmp">/tmp</h3>
<p>Occupons nous du partitionnement lié à <code>/tmp</code>, et déclarons l&rsquo;option la
plus importante, dans ce cas <code>noexec</code>, parce que nous ne voulons pas que
n&rsquo;importe qui se serve de ce répertoire pour lancer n&rsquo;importe quoi :</p>
<p><code>UUID=1a7a999d-1e26-45f7-96c0-7d381887350d /tmp            ext4    defaults,nodev,noexec,nosuid       0       2</code></p>
<h4 id="mise-en-garde-pour-tmp">Mise en garde pour /tmp</h4>
<p>Le problème principal est le même que pour les options sur les partitionnements
<code>/boot</code>, et <code>/usr</code>, en mettant l&rsquo;option <code>noexec</code>, lors des mises-à-jours
systèmes ou de l&rsquo;installation d&rsquo;un nouveau logiciel, cela <strong>ne pourra pas
s’exécuter correctement</strong> !</p>
<p>Il faut pour cela rajouter dans les invocations <em>pre</em> et <em>post</em> en
demandant de remonter le partitionnement <code>/tmp</code> avec les droits <code>exec</code>,
puis à les enlever après le traitement.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Pre-Invoke {&#34;mount -o remount,rw /boot&#34;;&#34;mount -o remount,rw /opt&#34;;&#34;mount -o remount,exec /tmp&#34;};</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Post-Invoke {&#34;mount -o remount,ro /boot&#34;;&#34;mount -o remount,ro /opt&#34;;&#34;mount -o remount,noexec /tmp&#34;};</span>
</span></span></code></pre></div><h4 id="informations-anssi-pour-tmp">Informations ANSSI pour /tmp</h4>
<p>La documentation ANSSI sur la configuration Linux recommande les options
<code>nosuid,nodev,noexec</code> pour la partition <code>/tmp</code>…</p>
<hr>
<h3 id="var-varlog-vartmp">/var, /var/log, /var/tmp</h3>
<p>Et les partitions <code>/var</code>, <code>/var/log</code>, <code>/var/tmp</code>  ?</p>
<ul>
<li><code>/var</code> : On peut rajouter les options <code>grpquota,nodev,usrquota</code>…</li>
</ul>
<p><code>UUID=e47dcfed-0d0a-486f-8f1c-63f9e8132590 /var            ext4    defaults,grpquota,nodev,usrquota        0       2</code></p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>ATTENTION, ce qui suit ne fonctionne pas avec SystemD !</strong></div>

<p>Quant au répertoire <code>/var/tmp</code>, il est intéressant de le supprimer, puis
de le lier vers le répertoire ou la partition <code>/tmp</code>, qui sera ainsi bien gérée.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# rm -rf /var/tmp
</span></span><span style="display:flex;"><span>:# ln -s /tmp /var/tmp
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Pensez à sauvegarder les fichiers dedans, pour les restaurer ensuite… au besoin !</div>

<h4 id="informations-anssi-pour-var-varlog-vartmp">Informations ANSSI pour /var, /var/log, /var/tmp</h4>
<p>La documentation ANSSI sur la configuration Linux recommande les options
<code>nosuid,nodev,noexec</code> pour toutes les partitions <code>/var</code>, <code>/var/log</code>,
<code>/var/tmp</code>…</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention à l&rsquo;impact de l&rsquo;usage de l&rsquo;option <code>noexec</code> sur la partition <code>/var</code>,
qui empêchera la création de répertoires et fichiers temporaires lors des
mises-à-jours, par exemple !</div>

<hr>
<h3 id="-la-partition-racine">/ la partition racine</h3>
<p>Il est de bon ton, en terme de sécurité système, d&rsquo;empêcher l&rsquo;usage de <strong>dev</strong>
pour la racine système :</p>
<p><code>UUID=7b8b0d04-7d60-44dd-98f3-6134065a42c3 /               ext4    errors=remount-ro,nodev 0       1</code></p>
<h3 id="srv">/srv</h3>
<p>Cette partition, dont le but actuel, est de &ldquo;cloisonner&rdquo; des services serveurs,
tels que web, base de données, a aussi sa propre recommandation de la part
de l&rsquo;ANSSI :</p>
<ul>
<li>l&rsquo;usage des options <code>nosuid,nodev</code> et de manière optionnelle, <em>si vous savez gèrer</em>,
les options <code>noexec,ro</code>… <br>
<em>il est clair que l&rsquo;option <code>ro</code> pose son lot de problèmes, ne serait-ce que pour
certains sites web qui ont besoin au moins d&rsquo;un répertoire où écrire… <br>
à moins que vous redirigez ce genre d&rsquo;écritures !</em></li>
</ul>
<h3 id="home">/home</h3>
<p>L&rsquo;ANSSI recommande les options <code>nosuid,nodev,noexec</code>…</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Attention, toutefois, si vous utilisez le répertoire <code>~/bin</code> qui, <em>dans les
distributions telles que Debian, Ubuntu, (et assimilées)</em>, est inclus dans la
variable d&rsquo;environnement <code>PATH</code>, puisque l&rsquo;option <code>noexec</code> vous empêchera
d&rsquo;exécuter tout binaire, même vos personnels !</div>

<h3 id="shm">shm</h3>
<p><strong>shm</strong> est l&rsquo;accronyme de <em>shared memory</em> ; en doux français : <em>mémoire partagée</em>.</p>
<p>Sécuriser le point de montage correspondant est intéressant, afin d&rsquo;empêcher
l&rsquo;attaque contre certains services par ce biais, tel que celui d&rsquo;un serveur web,
par exemple.</p>
<h4 id="runshm">/run/shm</h4>
<p>Si vous avez le répertoire <code>/run/shm</code>, configurez le fichier <code>/etc/fstab</code>, ainsi :</p>
<p><code>tmpfs     /run/shm    tmpfs       defaults,nodev,noexec,nosuid 0   0</code></p>
<h4 id="devshm">/dev/shm</h4>
<p>Si vous n&rsquo;avez que <code>/dev/shm</code>, qui normalement ne pointe pas vers <code>/run/shm</code>,
modifiez <code>/etc/fstab</code> en remplaçant <code>/run/shm</code>, par <code>/dev/shm</code>.</p>
<h2 id="utilisation">Utilisation</h2>
<h3 id="remonter-une-partition">Remonter une partition</h3>
<p>Bon, comme vous avez certainement dû le comprendre, pour remonter dynamiquement
un partitionnement, sans avoir à redémarrer le système, on utilise la commande
suivante - <em><strong>avec les droits administrateurs, bien sûr</strong></em> - :</p>
<p><code>:# mount -o remount,options /nom_partition</code></p>
<p>Et si vous avez le droit à une erreur, telle que <code>/partitionnement busy</code>,
préférez redémarrer la machine !</p>
<h2 id="tldr">TLDR</h2>
<h3 id="fichier-etcaptaptconfd00apt">Fichier /etc/apt/apt.conf.d/00apt</h3>
<p>Un exemple de fichier <code>/etc/apt/apt.conf.d/00apt</code> modifié selon les recommandations
ci-dessus :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Pre-Invoke{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,rw /boot&#34;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,exec /tmp&#34;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,exec /var&#34;;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">};</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">DPkg::Post-Invoke {</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,ro /boot&#34;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,noexec /tmp&#34;;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">&#34;mount -o remount,noexec /var&#34;;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">};</span>
</span></span></code></pre></div><h3 id="fichier-etcfstab">Fichier /etc/fstab</h3>
<p>Un exemple de fichier <code>/etc/fstab</code> modifié selon les recommandations ci-dessus :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">6a45556d-df24-4fa5-97fd-5761935c7cfe /               ext4    errors=remount-ro,nodev 0       1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /boot was on /dev/sda11 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">e703ff5e-8dd8-430b-b336-c2021477f2cf /boot           ext4    defaults,nodev,noexec,nosuid        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /boot/efi was on /dev/sda1 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">634A-AB2B  /boot/efi       vfat    umask=0077      0       1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /home was on /dev/sda10 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">d51067e6-899d-4455-bb87-62ec74e75418 /home           ext4    defaults,nodev,nosuid        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /opt was on /dev/sda9 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">ed5f8cdc-5298-485e-aaa0-52603440f129 /opt            ext4    defaults,nodev,nosuid        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /tmp was on /dev/sda8 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0f78ac20-f350-4a1b-ba0c-37e143cb64f5 /tmp            ext4    defaults,nodev,noexec,nosuid        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /usr was on /dev/sda5 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">70d74e44-ce91-4786-a747-a2fca4a2262a /usr            ext4    defaults,nodev,ro        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /usr/local was on /dev/sda6 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">e1f892e2-ebf9-4e7e-8640-f63a41f2df22 /usr/local      ext4    defaults,nodev        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /var was on /dev/sda3 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">50552290-0f4d-4a65-abfa-9fac98ae98d2 /var            ext4    defaults,nodev,noexec,grpquota,nosuid,usrquota        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># /var/log was on /dev/sda7 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">6dac116d-dc39-46e1-a324-55a2905ea266 /var/log        ext4    defaults,nodev,noexec,nosuid        0       2</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># swap was on /dev/sda4 during installation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">UUID</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">96dc1eab-0dc2-4fcb-b758-0d01450e12b5 none            swap    sw              0       0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">tmpfs   /dev/shm    tmpfs      defaults,nodev,nouser,nosuid 0   0</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Comment sécuriser sa distribution GNU/Linux en durcissant le partitionnement]]></summary>
        <published>2017-07-28T12:56:04+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0d87dc3d-1234-a3ec-4ab3-310d222b1473</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-block-attacks/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : bloquer certaines attaques ! (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Si Korben nous informe du <a href="http://korben.info/nginx-comment-bloquer-les-attaques-les-plus-courantes.html" rel="external">comment bloquer certaines
attaques</a>
pour et par le serveur web Nginx - sa manière de le faire n&rsquo;est pas
forcément des meilleures !</p>
<p>Utilisons le contexte <code>location</code>, et écrivons-les ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#776e71">## Block Queries
</span></span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;(\&#34;|%22).*(&lt;|&gt;|%3)&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;(javascript\:).*(\;)&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;(\|\.\./|`|=\&#39;$|=%27$)&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;(\;|\&#39;|\&#34;|%22).*(union|select|concat|insert|drop|update|md5|benchmark|or|and|if)&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;(&lt;|%3C).*script.*(&gt;|%3)&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;[a-zA-Z0-9_]=http://&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;[a-zA-Z0-9_]=(\.\.//?)+&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;[a-zA-Z0-9_]=/([a-z0-9_.]//?)+&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">&#34;.*(asp|bs)</span><span style="color:#ef6155">$&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span>  <span style="color:#48b685">&#34;.*(admin|cgi|manager|pma|user|wp|wordpress).*&#34;</span>  { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">&#34;^base64_(en|de)code\(.*\)|localhost|mosconfig&#34;</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Au lieu de retourner une erreur 403, informant que la
requête est valide, mais refusée par le serveur, préférez retourner une
erreur 444 - où le serveur refuse d&rsquo;envoyer toute information, et ferme
la connexion directement !</p>
<p><strong>c&rsquo;est cela aussi le pouvoir tant réputé de nginx</strong> ;-)</p>
</div>

<h2 id="documentation">Documentation</h2>
<ul>
<li><del><a href="http://wiki.nginx.org/IfIsEvil" rel="external">if is evil</a></del></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment bloquer certaines attaques web avec le serveur Nginx]]></summary>
        <published>2017-07-27T17:50:20+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0fa55017-5d06-1dcd-8e15-258f07d7d4ea</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/apt-gpg-error/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Apt : Gpg Error</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="apt" scheme="http://doc.huc.fr.eu.org/fr/tags/apt/" />
        <category term="erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <content type="html"><![CDATA[
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>2020 : Cette manière de faire est obsolète… veuillez plutôt consulter mon
article
<a class="inside" href="/fr/sys/debian/add-apt-key/" title="Lien interne vers l&#39;article : 'Apt : Ajouter une clé GPG'">Apt : Ajouter une clé GPG</a></p>
<p>!!!</p>
</div>

<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Un petit script bash pour aider à résoudre simplement l&rsquo;erreur gpg liée
à la mise-à-jour des dépôts debian, ubuntu…</p>
<p>Ce script, très simple, permet de lancer la suite de
commande gpg nécessaire à ajouter pour que les dépôts
ne retournent pas cette erreur :</p>
<pre tabindex="0"><code>W: GPG error: ftp://ftp.domain.org testing Release:
The following signatures couldn&#39;t be verified because the public key is not available: NO_PUBKEY 010203040A0B0C0D
W: There is no public key available for the following key IDs:
010203040A0B0C0D
</code></pre><h2 id="code">Code</h2>
<p>La solution :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg --keyserver keyserver.ubuntu.com --recv-key <span style="color:#ef6155">$1</span>
</span></span><span style="display:flex;"><span>gpg -a --export <span style="color:#ef6155">$1</span> | sudo apt-key add -
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Debian: résoudre l&#39;erreur de l&#39;outil apt : GPG Error]]></summary>
        <published>2017-07-27T16:05:08+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:96ec748e-f4c9-de7b-4c68-a51a4c492a2f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/configuration-securisee/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : Configuration Sécurisée</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le propos de cet article est d&rsquo;aider à comprendre ce qu&rsquo;il faut configurer
pour obtenir une configuration sécurisée de votre client SSH.</p>
<p>Cela nécessite <span hi>que votre version du client OpenSSH soit supérieure
à la version 6.5</span> !</p>
<h2 id="configuration">Configuration</h2>
<p>Côté client, le plus simple est de modifier votre fichier de
configuration, dans votre home personnel, <code>~/.ssh/config</code>…</p>
<hr>
<p>Cet article n&rsquo;aborde que la partie concernant le client ; pour la partie
serveur, merci de lire mon autre article : 
<a class="inside" href="/fr/sec/ssh/sshd-durci/" title="Lien interne vers l&#39;article : 'OpenSSH : Durcir la configuration du serveur SSH'">OpenSSH : Durcir la configuration du serveur SSH</a>

</p>
<h3 id="chiffrements">Chiffrements</h3>
<p>Les algorithmes de <strong>Chiffrement</strong> à autoriser :</p>
<p><code>Ciphers chacha20-poly1305@openssh.com</code></p>
<p>À vérifier au cas par cas… <br>
regardez donc le log d&rsquo;authentification sur votre serveur !</p>
<h3 id="échange-de-clés">Échange de clés</h3>
<p>Les <strong>algorithmes des clés d&rsquo;échange</strong> à privilègier sont :</p>
<p><code>KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com</code></p>
<h3 id="algorithmes-de-la-clé-dhôte">Algorithmes de la clé d&rsquo;Hôte</h3>
<p>Les recommandations actuelles pour les <strong>algorithmes des clés d&rsquo;hôte</strong> sont : <br>
<code>HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519</code></p>
<h3 id="message-authentication-codes">Message Authentication Codes</h3>
<p>Les algorithmes des <strong>Code d&rsquo;Authentification de Messages</strong> à définir sont : <br>
<code>MACs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com</code></p>
<h3 id="tldr">TL;DR</h3>
<p>Voici un exemple de configuration sécurisée minimal :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Host *</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Ciphers chacha20-poly1305@openssh.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">MACs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ChallengeResponseAuthentication no</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#CheckHostIP yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Compression yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#CompressionLevel 9 # unsupported!</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ControlMaster auto</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ControlPersist yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ControlPath ~/.ssh/socket-%r@%h:%p</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">HashKnownHosts yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ForwardAgent no</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ForwardX11 no</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ForwardX11Trusted yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">PasswordAuthentication yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Protocol 2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">PubkeyAuthentication yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ServerAliveInterval 30</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">ServerAliveCountMax 7</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#StrictHostKeyChecking yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">TCPKeepAlive yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#UseRoaming no # Do not using with ≥ v7! (for oldier versions)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">VerifyHostKeyDNS yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">VisualHostKey yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">AddKeysToAgent yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#UseKeychain yes</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">IdentityFile ~/.ssh/id_ed25519</span>
</span></span></code></pre></div><p>Selon le manpage officiel, les configurations personnalisées à certains
hôtes doivent être écrites avant la configuration générale <code>Host *</code> !</p>
<h2 id="utilisation">Utilisation</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><span class="red">ne pas utiliser les protocoles de chiffrement DSA, ECDSA</span>
,
mais <strong>utilisez <a href="/fr/sec/ssh/configuration-securisee/#nouvelle-clé-rsa-+-pkbdf">RSA</a> en forçant le
nombre de bits</strong> - <em>de 4096 à 16384 -</em>, <strong>ET en utilisant PKBDF</strong>, ou mieux
<strong>utilisez directement <a href="/fr/sec/ssh/configuration-securisee/#nouvelle-clé-ed25519">ED25519</a>, ayant déjà PKBDF</strong>.</div>

<p>Les créations suivantes sont à faire côté client, bien sûr !</p>
<h3 id="mettre-à-jour-vos-clés-rsa">Mettre-à-jour vos clés RSA</h3>
<p><code>ssh-keygen -o -p -f id_rsa -a 64</code></p>
<ul>
<li>L&rsquo;option <code>-f</code> spécifie le fichier de clé privée à utiliser.</li>
<li>L&rsquo;option <code>-o</code> est celle qui utilise le durcissement PKBDF.</li>
<li>et pour finir, l&rsquo;option <code>-a</code> définit le nombre de tours &ldquo;de moulinettes&rdquo; que
va effectuer la génération.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si cette option n&rsquo;est pas spécifiée, la valeur par défaut est <code>16</code>. <br>
Vous pouvez lui demander <code>1000</code> tours, néanmoins pour les paranoïaques
la valeur de <code>64</code> semble préférable ET suffisante.</div>

<h3 id="nouvelles-clés">Nouvelles clés</h3>
<h4 id="nouvelle-clé-ed25519">Nouvelle clé ED25519</h4>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Il n&rsquo;est pas nécessaire de spécifier l&rsquo;usage de l&rsquo;option <code>-o</code> ; en effet,
la génération des clés Ed25519 utilise toujours ce format par défaut !</div>

<p><code>ssh-keygen -t ed25519 -f fichier_id -a nb_tours</code></p>
<p>Tel que, par exemple :</p>
<p><code>ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -a 64</code></p>
<h4 id="nouvelle-clé-rsa--pkbdf">Nouvelle clé RSA + PKBDF</h4>
<p><code>ssh-keygen -t rsa -b nb_bits -f fichier_id -o -a nb_tours</code></p>
<p>Tel que, pour l&rsquo;exemple :</p>
<p><code>ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -o -a 64</code></p>
<h2 id="astuces">Astuces</h2>
<p>Si vous avez paramétré l&rsquo;option <code>LoginGraceTime</code> sur le serveur, pensez à
<strong>augmenter sa valeur, sinon</strong> vous aurez <strong>le droit à ne pas
pouvoir vous connecter, sans aucun message d&rsquo;erreur</strong> dans le log
d&rsquo;authentification.</p>
<p>En effet, selon le nombre de tours que vous avez paramétrés pour la
génération de votre clé, ou sa mise-à-jour, le déchiffrement et la
réponse du serveur prendra plus de temps, peut-être plus que le temps
d&rsquo;ouverture, de la fenêtre de connexion, autorisé.</p>
<h2 id="documentations">Documentations</h2>
<h3 id="manpages">Manpages</h3>
<ul>
<li>
<a class="man" href="https://man.openbsd.org/ssh" title="Page du Manuel OpenBSD pour : ssh">ssh</a>
, 
<a class="man" href="https://man.openbsd.org/ssh_config.5" title="Page du Manuel OpenBSD pour : ssh_config">ssh_config(5)</a>
</li>
<li>
<a class="man" href="https://man.openbsd.org/ssh-keygen" title="Page du Manuel OpenBSD pour : ssh-keygen">ssh-keygen</a>
</li>
</ul>
<h3 id="autres">Autres</h3>
<ul>
<li>Quand <a href="https://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html" rel="external">Martin Kleppman a écrit</a> sur le propos d&rsquo;améliorer la sécurité de ses clés privées SSH…</li>
<li><a href="http://blog.patshead.com/2013/09/generating-new-more-secure-ssh-keys.html" rel="external">Pat Regan</a> nous fait un petit rappel historique de comment utiliser PKCS#8 pour en aboutir à la conclusion d&rsquo;utiliser PKBDF…</li>
<li>ou comment <a href="http://www.tedunangst.com/flak/post/new-openssh-key-format-and-bcrypt-pbkdf" rel="external">Ted Unangst</a> nous explique comment monter à niveau ses vieilles clés en utilisant PKBDF…</li>
<li>Voici une très bonne lecture, sur le propos de <a href="https://stribika.github.io/2015/01/04/secure-secure-shell.html" rel="external">sécuriser son serveur SSH</a>, en utilisant les bons algorithmes, et autres méthodes d&rsquo;authentification… <em>(osbolète)</em></li>
<li>Voire le <a href="https://www.ssi.gouv.fr/uploads/2014/01/NT_OpenSSH.pdf" rel="external">référentiel de sécurité</a> de l&rsquo;ANSSI à-propos des recommandations de sécurité autour de SSH. <em>(cf : <a href="https://www.ssi.gouv.fr/administration/guide/recommandations-pour-un-usage-securise-dopenssh/" rel="external">https://www.ssi.gouv.fr/administration/guide/recommandations-pour-un-usage-securise-dopenssh/</a> )</em></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment configurer SSH pour une utilisation plus sécurisée, et une génération correcte des clés SSH.]]></summary>
        <published>2017-07-27T14:26:58+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:85182849-da04-f529-a3d5-7155cc06e887</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/software/filezilla-sftp-connection-closed-by-server-with-exitcode-10/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Filezilla : SFTP Connection closed by server with exitcode 10</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Filezilla" scheme="http://doc.huc.fr.eu.org/fr/tags/filezilla/" />
        <category term="SFTP" scheme="http://doc.huc.fr.eu.org/fr/tags/sftp/" />
        <category term="erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Vous avez le message d&rsquo;erreur en titre, avec Filezilla : <br>
<code>SFTP Connection closed by server with exitcode 10</code></p>
<p>Ouvrez le Gestionnaire de Sites, Onglet &ldquo;Paramètres de transfert&rdquo;, cliquez
sur la case à cocher <code>[ ] Limiter le nombre de connexions simultanées</code>
pour la paramétrer à <code>1</code><sup>*</sup>.</p>
<p>Validez et connectez-vous à nouveau !</p>
<hr>
<p><sup>*</sup> <em>ou selon votre configuration SSH, voire MySecureShell - Option LimitConnectionByUser</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment régler l&#39;erreur de connexion SFTP &#39;Connection closed by server with exitcode 10&#39; dans Filezilla]]></summary>
        <published>2017-07-27T15:00:38+02:00</published>
        <updated>2020-04-21T15:44:21+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:357e2bd1-9b45-d43b-db71-2463ff72ed4f</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-block-exec-scripts/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Bloquer l&#39;exécution de scripts (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Une petite astuce relative à nginx, afin de bloquer l&rsquo;exécution de scripts,
dans les répertoires où vous ne désirez pas qu&rsquo;ils s&rsquo;exécutent, tels que
ASP, PHP, Shell, etc :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~<span style="color:#48b685">*</span> <span style="color:#48b685">/(repertoire1|repertoire2|repertoire_xyz|image|css|js)/.*.(asp|cgi|jsp|php|pl|py|sh)</span>$ {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Comment bloquer l&#39;exécution de scripts avec le serveur web nginx]]></summary>
        <published>2017-07-27T14:53:46+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ae03dc74-7998-a6bf-65b7-3004c1b6ddbc</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-block-user-agent/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Bloquer &#39;User Agent&#39; (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <category term="UA" scheme="http://doc.huc.fr.eu.org/fr/tags/ua/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Bloquer un <abbr title="User Agent">UA</abbr>
 n&rsquo;est pas bien difficile avec nginx !</p>
<p>Utilisons le module <code>map</code> dans le contexte <code>http</code>, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_user_agent</span> <span style="color:#ef6155">$bad_bot</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~(?i)(&#34;&#34;|Curl|Wget)</span> <span style="color:#f99b15">1</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Dans le fichier de configuration, lié à votre domaine, rajouter :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$bad_bot</span><span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">403</span>; }
</span></span></code></pre></div>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><ul>
<li>Préférez l&rsquo;usage du code erreur 444 ;-)</li>
<li>Vous pouvez faire de même, bien sûr, pour bloquer de mauvais &ldquo;referers&rdquo; !</li>
</ul>
</div>

<h2 id="documentation">Documentation</h2>
<ul>
<li><del>if is evil](<a href="http://wiki.nginx.org/IfIsEvil)" rel="external">http://wiki.nginx.org/IfIsEvil)</a></del></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment bloquer un agent utilisateur web - (user agent) - avec le serveur web nginx]]></summary>
        <published>2017-07-27T14:42:43+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:41bd4339-1dbb-a16d-6e25-d53f20527c67</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-block-shellshock/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Bloquer ShellShock (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="Shellshock" scheme="http://doc.huc.fr.eu.org/fr/tags/shellshock/" />
        <category term="Bash" scheme="http://doc.huc.fr.eu.org/fr/tags/bash/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>Shellshock</strong> est une faille de sécurité présente dans le shell Bash,
découverte en Septembre 2014. <em>Normalement, cette faille a été corrigée
dans Bash ; il est hautement recommandé d&rsquo;avoir la version la plus récente.</em></p>
<p>L&rsquo;explication ci-dessous explique comment empêcher l&rsquo;accès depuis le
serveur web nginx.</p>
<p>Dans votre contexte <code>http</code>, utilisez la déclaration <code>map</code>, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_user_agent</span> <span style="color:#ef6155">$bad_bot</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~*\{.*\:\</span>; <span style="color:#5bc4bf">1</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$http_referer</span> <span style="color:#ef6155">$bad_referer</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~*\{.*\:\</span>; <span style="color:#5bc4bf">1</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>C&rsquo;est l&rsquo;expression régulière <code>*\{.*\:\;</code> qui fait son travail ;
à savoir qu&rsquo;on peut légèrement la raccourcir, et cela fonctionne,
apparemment, aussi : <code>*\{.*\:</code></p>
<p>Ensuite, vous utilisez les conditions suivantes pour fermer la connexion,
sans autre forme de procédé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$bad_bot</span><span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#48b685">(</span><span style="color:#ef6155">$bad_referer</span><span style="color:#48b685">)</span> { <span style="color:#5bc4bf">return</span> <span style="color:#f99b15">444</span>; }
</span></span></code></pre></div><p>Si ces conditions ne sont pas acceptées dans le contexte <code>http</code>,
déclarez-les dans le contexte <code>server</code> ;-)</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Si vous souhaitez ne pas logger ces attaques, il faut créer de nouvelles
<code>map</code>, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$bad_ua$bad_referer</span> <span style="color:#ef6155">$bads</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~1</span> <span style="color:#f99b15">1</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">map</span> <span style="color:#ef6155">$bads</span> <span style="color:#ef6155">$loggable</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">default</span> <span style="color:#f99b15">1</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">~1</span> <span style="color:#f99b15">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Puis soit dans le contexte <code>http</code>, soit dans le contexte <code>server</code>,
il vous faut cibler votre journal d&rsquo;accès, tel que :</p>
<p><code>access_log /path/to/access.log combined if=$loggable;</code></p>
</div>

<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="http://forum.nginx.org/read.php?2,257792,257814#msg-257814" rel="external">http://forum.nginx.org/read.php?2,257792,257814#msg-257814</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Shellshock_%28faille_informatique%29" title="Article Wikipédia : Shellshock_(faille_informatique)">Shellshock_(faille_informatique) <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Bloquer la faille ShellShock avec le serveur web nginx]]></summary>
        <published>2017-07-27T14:34:16+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ecd50ea8-7c9c-d658-12d6-083863910b3e</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-autoindex/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx Autoindex (astuce)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="autoindex" scheme="http://doc.huc.fr.eu.org/fr/tags/autoindex/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Tout petit mémo relatif à nginx, ou
<strong>comment faire pour qu&rsquo;apparaisse le listing d&rsquo;un répertoire, avec nginx ?</strong></p>
<p>Il faut utiliser l&rsquo;option <code>autoindex on;</code> !</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="http://nginx.org/en/docs/http/ngx_http_autoindex_module.html" rel="external">http://nginx.org/en/docs/http/ngx_http_autoindex_module.html</a></li>
</ul>
<h2 id="exemple">Exemple</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>Index of /apt/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>../
</span></span><span style="display:flex;"><span>archive.canonical/                                 25-Jan-2016 18:18                   -
</span></span><span style="display:flex;"><span>archive.ubuntu/                                    25-Jan-2016 18:18                   -
</span></span><span style="display:flex;"><span>epson/                                             06-Feb-2016 23:04                   -
</span></span><span style="display:flex;"><span>extra.linuxmint/                                   25-Jan-2016 18:55                   -
</span></span><span style="display:flex;"><span>libreoffice/                                       12-Feb-2016 23:40                   -
</span></span><span style="display:flex;"><span>packages.linuxmint/                                25-Jan-2016 19:50                   -
</span></span><span style="display:flex;"><span>security.ubuntu/                                   25-Jan-2016 18:18                   -
</span></span><span style="display:flex;"><span>sil/                                               13-Feb-2016 23:35                   -
</span></span><span style="display:flex;"><span>wine/                                              12-Feb-2016 23:40                   -
</span></span><span style="display:flex;"><span>README                                             03-Mar-2016 03:51                1694
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Nginx: lister automatiquement l&#39;index d&#39;un répertoire]]></summary>
        <published>2017-07-27T14:00:35+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ded2d279-e007-5304-b3d8-1b1bcebf30ca</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/software/raid-access-livecd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: RAID : Comment accéder avec un LiveCD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="RAID" scheme="http://doc.huc.fr.eu.org/fr/tags/raid/" />
        <category term="LiveCD" scheme="http://doc.huc.fr.eu.org/fr/tags/livecd/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>L&rsquo;objet de ce post est simplement un mémo, à savoir comment accéder à un
partitionnement RAID, non chiffré, et cela grâce à un LiveCD !</p>
<ul>
<li>Démarrer sur le LiveCD</li>
<li>Ouvrez une console terminal</li>
<li>Installer &lsquo;&lsquo;mdadm&rsquo;&rsquo; <sup>*</sup></li>
<li>Utiliser la commande mdadm, telle que : <code>mdadm --assemble --scan</code> <sup>*</sup> <br>
<em>cela aura pour effet de monter les différents partitionnements que
la commande sera capable de reconnaître</em>.</li>
<li>Et, si vous voulez écrire dans l&rsquo;une ou l&rsquo;autre des partitions, ainsi
montées, ouvrez un navigateur de fichiers. <sup>*</sup></li>
</ul>
<p><sup>*</sup> Ces opérations se font toujours en appelant les droits administrateurs !
<em>Autrement vous n&rsquo;y aurez qu&rsquo;un accès en lecture…</em></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce pour accèder à un RAID à partir d&#39;un LiveCD]]></summary>
        <published>2017-07-27T13:54:44+02:00</published>
        <updated>2020-04-20T15:24:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:246e507d-4e0c-bf11-38bd-0fc9ee6d76f5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/linux/dnscrypt/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Durcir Linux : utiliser Dnscrypt</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="dnscrypt" scheme="http://doc.huc.fr.eu.org/fr/tags/dnscrypt/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Cet article est très probablement trop ancien, pour refléter l&rsquo;actualité du
logiciel <strong>dnscrypt</strong>. Il a été écrit en 2017, et non mis-à-jour.</div>

<p>Nommé <strong>Durcir Linux : utiliser dnscrypt</strong> est un bien grand mot… en fait, nous
n&rsquo;allons pas durcir directement Linux, mais nous allons utiliser un petit
outil, bien pratique, dont le but est de chiffrer les communications DNS !</p>
<p><strong>DNSCrypt</strong> est un outil, à l&rsquo;origine développé par <a href="https://www.opendns.com/about/innovations/dnscrypt/" rel="external">OpenDNS</a>, qui
maintenant a sa vie propre, au-travers du site : <a href="https://dnscrypt.org" rel="external">dnscrypt.org</a>.</p>
<p>Revenons en au but de ce petit outil, à savoir d’authentifier les communications
DNS, entre votre client logiciel DNS, et les serveurs DNS que vous utilisez
pour pouvoir surfer sur Internet. Il utilise des signatures cryptographiques
pour communiquer. Il interroge des serveurs DNS publics, compatible avec l&rsquo;outil.</p>
<p>Il peut-être actif conjointement à votre serveur DNS cache local. <br>
<em>pour cela, je vous renvoie à la documentation officielle</em></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Bien comprendre que cela ne protège pas des failles dues à DNS. <strong>dnscrypt
authentifie le trafic DNS, avec un serveur DNS compatible</strong>, et ainsi empêche
qu&rsquo;un serveur malintentionné se fasse passer pour un serveur authentique.</p>
<p><strong>dnscrypt n&rsquo;est pas non plus un service VPN</strong>, et n&rsquo;a pas l&rsquo;intention de
fournir de tels services, vous ne pouvez pas faire passer tous vos flux TCP/IP,
ni UDP, à l&rsquo;intérieur… <br>
<strong>Seules les requêtes DNS, sur les ports 53 et 443, en UDP.</strong></p>
<p>Soyez avertis aussi que les serveurs DNS compatibles peuvent très bien
journaliser votre trafic !</p>
</div>

<p>Il fonctionne sur les protocoles IPv4 et IPv6.</p>
<h2 id="installation">Installation</h2>
<p>Du côté de Debian, et assimilés, le client existe dans les dépôts officiels,
pour toutes les versions de Debian, de stable à Sid.</p>
<p>Du côté des *Buntu, il existe les ppa suivants :</p>
<ul>
<li>celui de <a href="https://launchpad.net/~xuzhen666/+archive/ubuntu/dnscrypt" rel="external">Xu Zhen</a>,</li>
<li>ou mieux intégré, celui de <a href="https://launchpad.net/~anton+/+archive/ubuntu/dnscrypt" rel="external">Pascal Mons</a> - <em>je me baserai sur ce dernier</em></li>
</ul>
<p>à vous de les ajouter, puis de les installer.</p>
<p>Sinon, vous attendez la future LTS [[http://packages.ubuntu.com/search?suite=xenial&amp;searchon=names&amp;keywords=dnscrypt|Xenial]],
ou vous mettez-à-jour vers [[http://packages.ubuntu.com/search?suite=wily&amp;searchon=names&amp;keywords=dnscrypt|Willy]] !</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration principal est situé dans <code>/etc/default/dnscrypt-proxy</code>.</p>
<p>Vous y retrouverez différentes options faciles à comprendre !</p>
<h3 id="network-manager">Network Manager</h3>
<p>Pensez à bien modifier votre configuration dans l&rsquo;outil
Network Manager, et à paramétrer votre onglet [ Paramètres IPv4 ] en modifiant :</p>
<ul>
<li>la méthode sur &lsquo;Adresses automatiques uniquement (DHCP)&rsquo;,</li>
<li>puis à écrire dans le champ &lsquo;Serveurs DNS&rsquo;, la valeur suivante &lsquo;127.0.0.2&rsquo;,</li>
</ul>
<p>enregistrez !</p>
<h3 id="etcnetworkinterfaces">/etc/network/interfaces</h3>
<p>Si vous n&rsquo;utilisez pas Network Manager, modifiez directement votre fichier
<code>/etc/network/interfaces</code>, en ajouter la mention :</p>
<p><code>dns-nameservers 127.0.0.2</code></p>
<p>dans ce cas, pensez à redémarrer votre réseau !</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Oui, c&rsquo;est bien l&rsquo;adresse localhost <code>127.0.0.2</code>… <br>
car l&rsquo;outil <code>dnscrypt-proxy</code> travaille en relation avec <code>dnsmasq</code>, qui
lui fonctionne, par défaut, sur l&rsquo;adresse localhost normale.</p>
<p>Celui de Xu Zhen, ce sera l&rsquo;adresse localhost &lsquo;127.0.0.1&rsquo;.</p>
</div>

<h3 id="mise-en-garde">Mise en garde</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>À ce propos, si vous changez l&rsquo;option liée à l&rsquo;utilisateur en changeant son nom,
soit… c&rsquo;est votre droit - mais pensez à supprimer celui créé par l&rsquo;installateur,
et à créer le vôtre dans les mêmes conditions, tel que :</p>
<p><code>:# adduser --system --quiet --home /run/dnscrypt --shell /bin/false --group --disabled-password --disabled-login votre_user_dnscrypt</code></p>
</div>

<p>Cela est d&rsquo;ailleurs indiqué dans le fichier de configuration !</p>
<p>Vous êtes libre de changer aussi son répertoire maison ; pensez à vérifier
la création dudit répertoire, et à supprimer celui par défaut !</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Toutes les options que renferme le manpage lié à l&rsquo;outil sont utilisables dans
le fichier de configuration : <br>
<code>$ man dnscrypt</code></p>
<p>Il suffit dans ce cas d&rsquo;enlever les 2 symboles <code>--</code> qui les précédent.</p>
<p>À ce propos, si vous avez la bonne idée d&rsquo;utiliser l&rsquo;option <code>logfile</code>, telle que
<code>logfile=/var/log/dnscypt-proxy.log</code> et si vous utilisez <code>apparmor</code> aussi, il
faudra changer le profil apparmor lié à l&rsquo;outil, pour y ajouter la ligne
suivante : <br>
<code>/var/log/dnscypt-proxy.log rw,</code></p>
</div>

<p>Vous trouverez une liste des différents serveurs DNS compatibles, leurs noms,
leurs adresses IP, leurs clés d&rsquo;authentification, etc… <br>
dans le fichier <code>/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv</code>.</p>
<p>Vous pouvez changer ces informations dans le fichier de configuration.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment sécuriser sa distribution GNU/Linux en utilisant dnscrypt]]></summary>
        <published>2017-07-27T13:47:18+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:55404a1f-9a57-52a8-89bc-91fec5c30f8e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter-warning-suspicious-files-dev/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter : Warning: Suspicious file types found in /dev</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="dev" scheme="http://doc.huc.fr.eu.org/fr/tags/dev/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Rkhunter émet cet avis : <br>
<q>Warning: Suspicious file types found in /dev: /dev/.udev/rules.d/root.rules: ASCII text</q></p>
<p><strong>Normalement, en effet aucun fichier text ne devrait se trouver dans le
répertoire des fichiers périphériques, nommé <code>dev</code> !</strong></p>
<p>Mais si dans votre cas, votre installation système est fraîche, toute neuve,
pas de panique… en effet, depuis assez récemment, quelques distributions,
telle que Ubuntu, le font !</p>
<h2 id="analyse">Analyse</h2>
<p>Si le contenu du fichier en question est très similaire à ceci :</p>
<p><code>SUBSYSTEM==&quot;block&quot;, ENV{MAJOR}==&quot;252&quot;, ENV{MINOR}==&quot;0&quot;, SYMLINK+=&quot;root&quot;</code></p>
<p>Cela semble normal ! <br>
Et, donc être un fameux faux positif de rkhunter !</p>
<p>⇒ modifions le fichier <code>/etc/rkhunter.conf</code>, pour ajouter la ligne suivante,
dans la bonne section : <br>
<code>ALLOWDEVFILE=&quot;/dev/.udev/rules.d/root.rules&quot;</code></p>
<p>Puis recharger la base de données, avec l&rsquo;option <code>--propupd</code> de rkhunter,
et lancez un nouveau test !</p>
<p><strong>Si malheureusement</strong> ce n&rsquo;est pas le cas… une petite <strong>réinstallation système</strong> ?!</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;avis de détection par rkhunter : Warning: Suspicious file types found in /dev]]></summary>
        <published>2017-07-27T13:17:42+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d9a29c98-953e-1772-01a9-bab47a049c37</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter-warning-hidden-directory-found/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter : Warning: Hidden directory found</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="hidden" scheme="http://doc.huc.fr.eu.org/fr/tags/hidden/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Rkhunter émet cet avis : <br>
<q>Warning: Hidden directory found: /dev/.static</q>, ou <br>
<q>Warning: Hidden directory found: /dev/.udev</q></p>
<p>Si votre installation système est toute fraîche, n&rsquo;ayez pas peur, vous êtes
&ldquo;tombé&rdquo; sur un des fameux faux positif de ce binaire !</p>
<h2 id="configuration">Configuration</h2>
<p>Modifiez donc les variables <code>ALLOWHIDDENFILE</code> correspondante, dans le
fichier <code>/etc/rkhunter.conf</code> !</p>
<p><code>ALLOWHIDDENFILE=&quot;/dev/.static&quot;</code></p>
<p>Recharger la base de donnée, grâce à l&rsquo;option <code>--propupd</code>, et relancez le test.</p>
<p>Sinon, si ce n&rsquo;est pas le cas, malheureusement… il vous faudra envisager le pire !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;avis de détection par rkhunter : Warning: Hidden directory found]]></summary>
        <published>2017-07-27T10:58:31+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a0626de6-e7b9-0fc5-afd5-22228d1c0082</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter-warning-hidden-file-found/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter : Warning: Hidden file found</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="hidden" scheme="http://doc.huc.fr.eu.org/fr/tags/hidden/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Rkhunter émet cet avis : <br>
<quote>Warning: Hidden file found: /dev/.initramfs: symbolic link to /run/initramfs&rsquo;</quote> !</p>
<p>Si votre installation système est toute fraîche, n&rsquo;ayez pas peur, vous êtes
&ldquo;tombé&rdquo; sur un des fameux faux positif de ce binaire !</p>
<h2 id="configuration">Configuration</h2>
<p>Modifions le fichier <code>/etc/rkhunter.conf</code>, pour ajouter : <br>
<code>ALLOWHIDDENFILE=&quot;/dev/.initramfs&quot;</code></p>
<p>Recharger la base de donnée, grâce à l&rsquo;option <code>--propupd</code>, et relancez le test.</p>
<p>Sinon, si ce n&rsquo;est pas le cas, malheureusement… il vous faudra envisager le pire !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;avis de détection par rkhunter : Warning: Hidden file found]]></summary>
        <published>2017-07-27T10:48:31+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d9f99678-df31-d2b5-0b9f-5575184f9ba3</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-error-404-fail-permission-denied/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Erreur 404 ; failed (13: Permission denied)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="404" scheme="http://doc.huc.fr.eu.org/fr/tags/404/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Vous avez un message <strong>Error 404</strong>, sur une des pages visitées.</p>
<p>Et les logs du server web nginx vous avertissent de ce message :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">2016/02/13 11:35:52 [crit] 995#0: *48 open() &#34;/srv/www/site.web/www/&#34; failed (13: Permission denied), (…)
</code></pre><p><strong>Modifiez les droits en écriture à la racine de votre site !</strong></p>
<p>Par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# chmod <span style="color:#f99b15">0705</span> /srv/www/site.web/www
</span></span></code></pre></div><p>Même pas besoin de redémarrer nginx !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;erreur 404 - Error 404 - liée à des problèmes de droits sur répertoires et fichiers pour nginx]]></summary>
        <published>2017-07-27T07:11:48+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d7f639fa-6d3e-2af1-b0b4-739285a4f8d8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/linux/chattr/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Durcir Linux : Utiliser chattr</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="chattr" scheme="http://doc.huc.fr.eu.org/fr/tags/chattr/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Dans la continuité de mon article précédent <strong>
<a class="inside" href="/fr/sec/linux/durcir-partitionnement/" title="Lien interne vers l&#39;article : 'Durcir Linux : modifier le partitionnement'">Durcir Linux : modifier le partitionnement</a>

</strong>
il est une commande intéressante à utiliser : <code>chattr</code></p>
<p><strong>Cet outil permet de modifier les attributs de fichiers, répertoires.</strong></p>
<p>Il existe une option qui est fortement pratique : l&rsquo;option <code>i</code> - <em>dont le
but est de rendre figé, immuable l&rsquo;état d&rsquo;un fichier, ou répertoire et
d&rsquo;interdire toute modification ultérieure, même par l&rsquo;administrateur système,
généralement nommé <code>root</code></em>.</p>
<p>Les répertoires à protéger, tout particulièrement, sont :</p>
<ul>
<li><code>/bin</code>,</li>
<li><code>/boot</code>,</li>
<li><code>/etc</code>,</li>
<li><code>/usr</code>,</li>
<li><code>/root</code>,</li>
<li><code>/sbin</code>,</li>
<li>ainsi que les fichiers liés à : <code>/initrd</code>, <code>/lib</code>, <code>/lib64</code>, <code>/vmlinuz</code></li>
</ul>
<p>⇒ Pour protéger/figer/rendre immuable, un petit coup de commande :</p>
<pre tabindex="0"><code>chattr -R +i /bin /boot /etc /usr /root /sbin /lib* /initrd* /vmlinuz* 2&gt; /dev/null
chattr -R -i /etc/adjtime /etc/blkid.tab /etc/mtab /etc/network/run /etc/udev/rules.d 2&gt; /dev/null
</code></pre>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">La deuxième ligne est importante, car ces fichiers ne doivent pas être figés,
sinon le système ne peut s&rsquo;en servir !</div>

<p>⇒ Pour enlever l&rsquo;option <code>i</code> sur lesdits répertoires et fichiers, en question,
il suffit d&rsquo;écrire la commande ainsi :</p>
<p><code>chattr -R -i /boot /usr /bin /sbin /lib* /root /vmlinuz* /initrd* /etc 2&gt; /dev/null</code></p>
<h2 id="mise-en-garde">Mise en garde</h2>
<p>Tout outil nécessitant une modification système, comme par exemple <strong>visudo</strong>,
ou les outils de gestion de paquets, tels que ceux ci-dessous, impose la
gymnastique de rendre muable avant leur usage, et d&rsquo;avoir le réflexe de
figer en suivant !</p>
<p>N&rsquo;oubliez pas que si le système vous refuse l&rsquo;action, c&rsquo;est que vous avez
probablement figer l&rsquo;état de différents binaires. ;-)</p>
<h3 id="apt-dpkg-synaptic">apt, dpkg, synaptic</h3>
<p>Ces commandes peuvent être insérées dans un script, pour vous faciliter
la vie, et mieux, aussi vous devriez les intégrer à votre script de gestion
<code>apt</code>.</p>
<p>Si jamais vous avez la bonne idée d&rsquo;abuser de cette commande, veuillez
comprendre absolument qu&rsquo;avec les outils <strong>apt</strong>, <strong>dpkg</strong>, <strong>synaptic</strong>, -
<em>et très certainement, tout outil gérant l&rsquo;installation logicielle</em> -, il vous
faudra :</p>
<ul>
<li>utiliser l&rsquo;option <code>-i</code> ;</li>
<li>utilisez l&rsquo;outil d&rsquo;installation logiciel,</li>
<li>et veillez à remettre l&rsquo;option <code>+i</code> en suivant…</li>
</ul>
<p>Vous êtes avertis, autrement vous seriez surpris par quelques dysfonctionnements.</p>
<h2 id="utilisation">Utilisation</h2>
<p>Dans le fichier <code>/etc/apt/apt.conf.d/00apt</code>, ajouter :</p>
<ul>
<li>en première ligne, dans l&rsquo;invocation <em>pre</em>, un appel vers le script ci-dessous,
tel que :</li>
</ul>
<pre tabindex="0"><code>DPkg::Pre-Invoke{
   &#34;/repertoire/chattr_sys 0&#34;;
(…)
}
</code></pre><ul>
<li>et, en dernière ligne, dans l&rsquo;invocation <em>post</em> :</li>
</ul>
<pre tabindex="0"><code>DPkg::Post-Invoke {
(…)
   &#34;/repertoire/chattr_sys 1&#34;;
}
</code></pre><h3 id="script-shell">Script shell</h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Author: Stéphane HUC</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># mail: devs@stephane-huc.net</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># License: GNU/GPL 3</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Github: https://git.framasoft.org/hucste/tools</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Date: 2016/05/12</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Change attributes system</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">###</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">arg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">dirname</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>dirname <span style="color:#815ba4">$(</span>readlink -f -- <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$0</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">))</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">email_to</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;email@domain.tld&#34;</span> <span style="color:#776e71"># write your mail, here</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">email_from</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Admin &lt;admin@domain.tld&gt;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">mail</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>  <span style="color:#776e71"># if u wish mail, set to 1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">HOST</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#815ba4">$(</span>cat /etc/hostname<span style="color:#815ba4">)</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>active<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    chattr -R +i /bin /boot /chroot /etc /opt /usr /root /sbin /lib* /initrd* /vmlinuz* 2&gt; /dev/null
</span></span><span style="display:flex;"><span>    chattr -R -i /etc/adjtime /etc/blkid.tab /etc/mtab /etc/network/run /etc/udev/rules.d /var/lib /var/run 2&gt; /dev/null
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#34;Chattr immutable: active\n&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>disable<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    chattr -R -i /bin /boot /chroot /etc /opt /usr /root /sbin /lib* /initrd* /vmlinuz* 2&gt; /dev/null
</span></span><span style="display:flex;"><span>    printf <span style="color:#48b685">&#34;Chattr immutable: disable\n&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>send_mail<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        1|on|true<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">mssg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;ACTIVE&#34;</span> ;;
</span></span><span style="display:flex;"><span>        0|off|false<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">mssg</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;DISABLE&#34;</span> ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">[</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$mail</span><span style="color:#48b685">&#34;</span> -gt <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> echo <span style="color:#48b685">&#34;Chattr immutable: </span><span style="color:#f99b15">${</span><span style="color:#ef6155">mssg</span><span style="color:#f99b15">}</span><span style="color:#48b685"> on </span><span style="color:#ef6155">$HOST</span><span style="color:#48b685">&#34;</span> | mail -S <span style="color:#ef6155">from</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">email_from</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> -s <span style="color:#48b685">&#34;Chattr immutable ~ </span><span style="color:#ef6155">$HOST</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">email_to</span><span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    sleep <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    unset mssg
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>launcher<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$arg</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>        1|on|true<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            active;
</span></span><span style="display:flex;"><span>            send_mail <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$arg</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>        0|off|false<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            disable;
</span></span><span style="display:flex;"><span>            send_mail <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$arg</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>        *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>            clear
</span></span><span style="display:flex;"><span>            <span style="color:#ef6155">N</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;service </span><span style="color:#f99b15">${</span><span style="color:#ef6155">0</span>##*/<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>            echo <span style="color:#48b685">&#34;Usage: </span><span style="color:#ef6155">$N</span><span style="color:#48b685"> 0|off|false to disable immutable systems...&#34;</span> &gt;&amp;<span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>            echo <span style="color:#48b685">&#34;Usage: </span><span style="color:#ef6155">$N</span><span style="color:#48b685"> 1|on|true to active immutable systems...&#34;</span> &gt;&amp;<span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>            exit <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>verify_uid<span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#815ba4">$(</span>id -u<span style="color:#815ba4">)</span> -ne <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>        printf <span style="color:#48b685">&#34;[ \\33[1;31m %s \\33[0;39m ] %s \n&#34;</span> <span style="color:#48b685">&#34;KO&#34;</span> <span style="color:#48b685">&#34;Need to get rights admins!&#34;</span>
</span></span><span style="display:flex;"><span>        exit <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>verify_uid
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>launcher
</span></span></code></pre></div><p>Vous pouvez retrouver la dernière version de ce script sur mon <a href="https://framagit.org/hucste/tools/-/raw/master/Debian/chattr_sys" rel="external">gitlab</a> !</p>
<h2 id="documentation">Documentation</h2>
<h3 id="manpage">Manpage</h3>
<ul>
<li>un coup de <strong>manpage</strong>, vous renseignera encore plus profondément : <code>$ man chattr</code></li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment sécuriser sa distribution GNU/Linux en utilisant le binaire chattr]]></summary>
        <published>2017-07-27T07:07:17+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:92e6e9dc-d778-31b9-decc-914dd9e648f0</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/linux-firewall-icmpv6/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Linux : firewall ICMPv6</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="ICMPv6" scheme="http://doc.huc.fr.eu.org/fr/tags/icmpv6/" />
        <category term="Ip6tables" scheme="http://doc.huc.fr.eu.org/fr/tags/ip6tables/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou cette fois-ci, comment titrer : <strong>Filtrer le protocole ICMPv6 sous Linux</strong> -
<em>l&rsquo;équivalent du protocole ICMP mais pour IPv6</em></p>
<p>Il y a quelques heures, j&rsquo;ai écrit cet autre

<a class="inside" href="/fr/sec/firewall/linux-firewall-icmp/" title="Lien interne vers l&#39;article : 'Linux : firewall ICMP'">mémo</a>
… <br>
maintenant, je retranscris à-propos des mesures de filtrage à mettre en
place autour de ce protocole qu&rsquo;est ICMPv6.</p>
<p>Je ne vais pas faire un rappel de ce pourquoi existe ce protocole, ni du
fait que mal utilisé, il peut-être dangereux ; et, bien sûr, malheureusement,
il y aura toujours des gens pour mal l&rsquo;utiliser !</p>
<h2 id="gérer-icmpv6">Gérer ICMPv6</h2>
<h3 id="les-codes-icmpv6-à-refuser">Les codes ICMPv6 à refuser</h3>
<p>Par prudence, il est recommandable de filtrer tous les codes expérimentaux,
tels que 100, 101, 200, et 201, ainsi que les codes réservés pour le futur,
à savoir les codes 127 et 255.</p>
<p>Il est recommandé de bloquer les codes suivants :</p>
<ul>
<li><strong>5</strong> à <strong>99</strong> : ces codes sont non alloués !</li>
<li><strong>100</strong>, <strong>101</strong> : codes expérimentaux</li>
<li><strong>102</strong> à <strong>126</strong> : codes non alloués</li>
<li><strong>137</strong> - Redirect Message - sauf en cas de nécessité</li>
<li><strong>138</strong> - Router Renumbering</li>
<li><strong>139</strong> - ICMP Node Information Query</li>
<li><strong>140</strong> - ICMP Node Information Response</li>
<li><strong>144</strong> - Home Agent Address Discovery Request Message</li>
<li><strong>145</strong> - Home Agent Address Discovery Reply Message</li>
<li><strong>146</strong> - Mobile Prefix Solicitation</li>
<li><strong>147</strong> - Mobile Prefix Advertisement</li>
<li><strong>150</strong> - Seamoby Experimental - sauf en cas de nécessité</li>
<li><strong>154</strong> à <strong>199</strong> : codes non alloués</li>
<li><strong>200</strong>, <strong>201</strong> : codes expérimentaux</li>
<li><strong>202</strong> à <strong>254</strong> : codes non alloués</li>
</ul>
<h3 id="les-codes-icmpv6-à-limiter">Les codes ICMPv6 à limiter</h3>
<p>Les recommandations sont de limiter, en entrée et en sortie de machine,
tous les codes de type :</p>
<ul>
<li><strong>1</strong> - Destination Unreachable</li>
<li><strong>4</strong> - Parameter Problem Message</li>
</ul>
<p>Les recommandations suivantes sont de limiter en entrée seulement, tous
les codes suivants :</p>
<ul>
<li><strong>2/0</strong> - Packet Too Big Message</li>
<li><strong>3</strong> - Time Exceeded Message</li>
<li>et tous les autres codes existants, dont particulièrement :
<ul>
<li>le code <strong>128/0</strong> - Echo Request message <em>(le ping)</em> -</li>
<li>et le code <strong>129/0</strong> - Echo reply message <em>(le pong)</em>.</li>
</ul>
</li>
</ul>
<h3 id="précisions-utiles">Précisions utiles</h3>
<p>Concernant les codes suivants, il est précisé, dans leur RFC correspondante,
leur format de message :</p>
<ul>
<li>
<p>tous les codes dits <strong>























































<span lang="en">MLD <em>(Multicast Listener Discovery)</em></span>























































</strong>
donc <strong>130</strong>, <strong>131</strong>, <strong>132</strong> et <strong>143</strong> - et <strong>MLDv2</strong> doivent être
envoyés depuis une adresse dont la source est un lien local IPv6,
avec un <code>hop limit</code> à <code>1</code></p>
<ul>
<li><em>selon la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-2710">RFC 2710</a></em> ;
<em>le type 143 étant défini par la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-3810">RFC 3810</a></em>.</li>
</ul>
</li>
<li>
<p>tous les codes dits <strong>





























































<span lang="en">ND <em>(Neighbor Discovery)</em></span>

















































</strong> de <strong>133</strong>
à <strong>137</strong> doivent être envoyés avec un <code>hop-limit</code> à <code>255</code> -
<em>définis par la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-4861">RFC 4861</a></em>. <br>
Quelques précisions concernant ces codes :</p>
<ul>
<li>
<p>le code <strong>133</strong> - <strong>Router Solicitation</strong> - doit être envoyé par une
source ayant forcément une adresse IP assignée, ou depuis une adresse
non spécifiée si l&rsquo;interface réseau n&rsquo;a pas encore d&rsquo;adresse IP
assignée, vers tout routeur.</p>
</li>
<li>
<p>le code <strong>134</strong> - <strong>Router Advertisement</strong> - doit ABSOLUMENT être
envoyé par un routeur, émettant un avis de routeur périodique, ou
une réponse à une sollicitation de routeur, à destination de tout
nœud multicast ou à l&rsquo;adresse source invoquant le routeur.</p>
</li>
<li>
<p>le code <strong>135</strong> - <strong>Neighbor Solicitation</strong> - doit être envoyé par
une source ayant forcément une adresse IP assignée, ou depuis une
adresse non spécifiée si l&rsquo;interface réseau n&rsquo;a pas encore d&rsquo;adresse
IP assignée, vers tout nœud multicast.</p>
</li>
<li>
<p>le code <strong>136</strong> - <strong>Neighbor Advertisement</strong> - doit ABSOLUMENT être
envoyé par une adresse IP assignée, vers l&rsquo;adresse source invoquant
le code 135, ou vers tout nœud multicast, s&rsquo;il n&rsquo;y a pas d&rsquo;adresse
assignée.</p>
</li>
<li>
<p>le code <strong>137</strong> - <strong>Redirect Message</strong> - doit ABSOLUMENT être envoyé
par une adresse IP assignée, lien local IPv6, d&rsquo;un routeur vers
l&rsquo;adresse source qui a demandé la redirection du message.</p>
</li>
</ul>
</li>
<li>
<p>les codes dits <strong>

































































<span lang="en">NIQ <em>(Node Information Queries)</em></span>













































</strong> - donc
<strong>139</strong> - <strong>ICMP Node Information Query</strong> - et <strong>140</strong> -
<strong>ICMP Node Information Response</strong> -
doivent refuser toutes requêtes venant d&rsquo;adresses IPv6 dites globales
et devraient appliquer l&rsquo;emploi de l&rsquo;option <code>limit</code>. <br>
À savoir qu&rsquo;il y a d&rsquo;autres mesures de sécurité, plus complexes…
<em><a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-4620">RFC 4620</a></em></p>
</li>
<li>
<p>les codes dits <strong>






























































<span lang="en">ND ID <em>(Neighbor Discovery Inverse Discovery)</em></span>
















































</strong> -
donc <strong>141</strong> - <strong>Inverse Neighbor Discovery Solicitation Message</strong> -
et <strong>142</strong> - <strong>Inverse Neighbor Discovery Advertisement Message</strong> -,
tous deux doivent avoir pour source une adresse IP assignée - <em>codes
définis par la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-3122">RFC 3122</a></em> :</p>
<ul>
<li>le code <strong>141</strong> doit être envoyé à destination de tout noeud multicast,
dont le format est de type <strong>FF02::1</strong></li>
<li>le code <strong>142</strong> doit répondre seulement à une requête de type 141.</li>
</ul>
</li>
<li>
<p>les codes dits <strong>

















































































<span lang="en">SEND <em>(SEcure Neighbor Discovery)</em></span>





























</strong> - donc
<strong>148</strong> - <strong>Certification Path Solicitation Message</strong> - et <strong>149</strong> -
<strong>Certification Path Advertisement Message</strong> - doivent être envoyés
avec un <code>hop-limit</code> à <code>255</code> - <em>c&rsquo;est la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-3971">RFC 3971</a>
qui définit ces codes</em>.</p>
</li>
<li>
<p>les codes dits <strong>


























































<span lang="en">MRD <em>(Multicast Router Discovery)</em></span>




















































</strong> - donc
<strong>151</strong> à <strong>153</strong>, <em>définis par la <a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-4286">RFC 4286</a></em>,
doivent être envoyés depuis une addresse assignée, lien local IPv6,
et avoir un <code>hop-limit</code> à <code>255</code>.</p>
</li>
</ul>
<h2 id="exemples">Exemples</h2>
<h3 id="icmpv6-en-mode-parano">ICMPv6 en mode parano</h3>
<p>En mode paranoïaque, cela donne ce genre de règles :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 -m limit --limit 3/s --limit-burst 7 -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -s fe80::/64 -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 134</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT # Type: 135</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 136</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT -p icmpv6 -j DROP</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A OUTPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 --icmpv6-type echo-reply -m conntrack --ctstate NEW -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -d ff02::/16 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT # Type: 133</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT # Type: 135</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT # Type: 136</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -d ff02::/16 -p icmpv6 --icmpv6-type 143/0 -j ACCEPT # Type: 143/0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT -p icmpv6 -j DROP</span>
</span></span></code></pre></div><h3 id="icmp-filtré-limité">ICMP filtré, limité</h3>
<p>Voici, pour l&rsquo;exemple, basé sur la compréhension des recommandations IETF,
des règles ICMP filtrées, limitées ; puis de rejeter tous les autres codes,
avec le message <code>icmp6-adm-prohibited</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># INPUT RULES</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -N INPUT_ICMPV6</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A INPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate INVALID -j DROP</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 -m limit --limit 3/s --limit-burst 7 -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 1 -m conntrack --ctstate NEW -j ACCEPT   # destination-unreachable; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 2/0 -m conntrack --ctstate NEW -j ACCEPT   # packet too big; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/0 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/1 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Should Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/0 -m conntrack --ctstate NEW -j ACCEPT   # parameter pb: Erroneous header field encountered; Should Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/1 -m conntrack --ctstate NEW -j ACCEPT   # parameter pb: Unrecognized Next Header Type encountered; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/2 -m conntrack --ctstate NEW -j ACCEPT   # parameter pb: Unrecognized IPv6 option encountered; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 100 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 101 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 127 -j DROP   # error messages ICMPv6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 128/0 -m conntrack --ctstate NEW -j ACCEPT   # ping tool: echo request message; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 129/0 -m conntrack --ctstate NEW -j ACCEPT  # ping tool: echo reply message; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 131/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 132/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># address configuration and routeur selection mssg (received with hop limit = 255)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 133/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -s fe80::/64 -p icmpv6 --icmpv6-type 134/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 135/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 136/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 137/0 -j DROP   # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 138/0 -j DROP   # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 139/0 -j DROP   # Should Be Dropped Unless a Good Case Can Be Made</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP   # Should Be Dropped Unless a Good Case Can Be Made</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 141/0 -d ff02::1 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 142/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 143 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># needed for mobylity</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 144/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 145/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 146/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 147 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># SEND certificate path notification mssg (received with hop limit = 255)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># multicast routeur discovery mssg (need link-local src address and hop limit = 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 151 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 152 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 153 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 201 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 255 -j DROP   # error messages ICMPv6</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># all others are dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#ip6tables -A INPUT_ICMPV6 -p icmpv6 ! --icmpv6-type -j DROP or -j REJECT --reject-with icmp6-adm-prohibited ⇐ this type seems not correctly supported!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A INPUT_ICMPV6 -p icmpv6 -j REJECT --reject-with no-route</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># OUTPUT RULES</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -N OUTPUT_ICMPV6</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate INVALID -j DROP</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 1 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT   # destination-unreachable; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 2/0 -m conntrack --ctstate NEW -j ACCEPT   # packet too big; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/0 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/1 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Should Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/0 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT   # parameter pb: Erroneous header field encountered; Should Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/1 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT   # parameter pb: Unrecognized Next Header Type encountered; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/2 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT   # parameter pb: Unrecognized IPv6 option encountered; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 100 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 101 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 127 -j DROP   # error messages ICMPv6</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 128/0 -m conntrack --ctstate NEW -j ACCEPT   # ping tool: echo request message; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 129/0 -m conntrack --ctstate NEW -j ACCEPT  # ping tool: echo reply message; Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 131/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 132/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># address configuration and routeur selection mssg (received with hop limit = 255)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 133/0 -d ff02::/16 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">##ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 134/0 -d fe80::/64 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 135/0 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 136/0 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 137/0 -j DROP   # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 138/0 -j DROP   # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 139/0 -j DROP   # Should Be Dropped Unless a Good Case Can Be Made</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP   # Should Be Dropped Unless a Good Case Can Be Made</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 141/0 -d ff02::1 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 142/0 -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 143 -d ff02::/16 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># needed for mobylity: except if the context requires it, then it will be necessary to limit them</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 144/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 145/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 146/0 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 147 -j DROP  # Will Be Dropped Anyway</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># SEND certificate path notification mssg (received with hop limit = 255)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 148 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 149 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># multicast routeur discovery mssg (need link-local src address and hop limit = 1)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 151 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 152 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 153 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT   # Must Not Be Dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 201 -j DROP   # private experimentation</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 255 -j DROP   # error messages ICMPv6</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># all others are dropped</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#ip6tables -A OUTPUT_ICMPV6 -p icmpv6 ! --icmpv6-type -j DROP or -j REJECT --reject-with icmp6-adm-prohibited # ⇐ this type seems not correctly supported!</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -j REJECT --reject-with no-route</span>
</span></span></code></pre></div><h2 id="documentations">Documentations</h2>
<p>Je ne vais pas reprendre le petit laïus sur IETF , ou IANA, mais simplement
rappeler de bonnes lectures à faire.</p>
<p><em>Si jamais, vous avez d&rsquo;autres &ldquo;tuyaux&rdquo; du même acabit, n&rsquo;hésitez pas m&rsquo;envoyer
un commentaire par mail.</em></p>
<ul>
<li>
<p>les différents <a href="https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml" rel="external">paramètres ICMPv6</a></p>
</li>
<li>
<p>la <strong><a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-4890">RFC 4890</a></strong></p>
</li>
<li>
<p>la <strong><a href="/fr/sec/firewall/linux-firewall-icmpv6/#rfc-5927">RFC 5927</a></strong></p>
</li>
<li>
<p>le <span lang="en"><a href="https://tools.ietf.org/html/draft-ietf-opsec-icmp-filtering-04" rel="external">draft ICMP filtering</a></span></p>
</li>
<li>
<p>le <span lang="en"><a href="https://tools.ietf.org/id/draft-ietf-v6ops-icmpv6-filtering-recs-02.txt" rel="external">draft ICMPv6 filtering</a></span></p>
</li>
<li>
<p><a href="https://connect.ed-diamond.com/GNU-Linux-Magazine/glmfhs-041/netfilter-et-le-filtrage-du-protocole-ipv6" rel="external">GNU Linux Magazine : Netfilter et le filtrage du protocole IPv6</a></p>
</li>
</ul>
<hr>
<p>
<h3 id="rfc-2710">RFC 2710</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc2710" title="RFC 2710 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc2710" title="RFC 2710 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc2710.txt" title="RFC 2710 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc2710.html" title="RFC 2710 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc2710.txt.pdf" title="RFC 2710 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc2710.txt" title="RFC 2710 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-3122">RFC 3122</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc3122" title="RFC 3122 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc3122" title="RFC 3122 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc3122.txt" title="RFC 3122 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc3122.html" title="RFC 3122 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc3122.txt.pdf" title="RFC 3122 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc3122.txt" title="RFC 3122 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-3810">RFC 3810</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc3810" title="RFC 3810 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc3810" title="RFC 3810 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc3810.txt" title="RFC 3810 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc3810.html" title="RFC 3810 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc3810.txt.pdf" title="RFC 3810 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc3810.txt" title="RFC 3810 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-3971">RFC 3971</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc3971" title="RFC 3971 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc3971" title="RFC 3971 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc3971.txt" title="RFC 3971 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc3971.html" title="RFC 3971 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc3971.txt.pdf" title="RFC 3971 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc3971.txt" title="RFC 3971 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-4286">RFC 4286</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4286" title="RFC 4286 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4286" title="RFC 4286 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4286.txt" title="RFC 4286 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4286.html" title="RFC 4286 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4286.txt.pdf" title="RFC 4286 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4286.txt" title="RFC 4286 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-4620">RFC 4620</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4620" title="RFC 4620 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4620" title="RFC 4620 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4620.txt" title="RFC 4620 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4620.html" title="RFC 4620 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4620.txt.pdf" title="RFC 4620 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4620.txt" title="RFC 4620 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-4861">RFC 4861</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4861" title="RFC 4861 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4861" title="RFC 4861 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4861.txt" title="RFC 4861 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4861.html" title="RFC 4861 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4861.txt.pdf" title="RFC 4861 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4861.txt" title="RFC 4861 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-4890">RFC 4890</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4890" title="RFC 4890 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4890" title="RFC 4890 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4890.txt" title="RFC 4890 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4890.html" title="RFC 4890 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4890.txt.pdf" title="RFC 4890 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4890.txt" title="RFC 4890 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-5927">RFC 5927</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc5927" title="RFC 5927 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc5927" title="RFC 5927 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc5927.txt" title="RFC 5927 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc5927.html" title="RFC 5927 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc5927.txt.pdf" title="RFC 5927 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc5927.txt" title="RFC 5927 : au format Text">TXT</a>
	</dd>
</dl>
</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Filtrer de manière sécurisé le protocole ICMPv6 sous Linux : exemples avec le parefeu Ip6tables]]></summary>
        <published>2017-07-26T22:22:02+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a5a17294-4b7e-6d7a-97e4-e6e66fe3c530</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/firewall/linux-firewall-icmp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Linux : firewall ICMP</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="firewall" scheme="http://doc.huc.fr.eu.org/fr/tags/firewall/" />
        <category term="ICMP" scheme="http://doc.huc.fr.eu.org/fr/tags/icmp/" />
        <category term="Iptables" scheme="http://doc.huc.fr.eu.org/fr/tags/iptables/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou comment titrer : <strong>Filtrer le protocole ICMP sous Linux</strong>.</p>
<p>Certains déclament qu&rsquo;il faut absolument tout bloquer, terminer les commandes
telles <code>traceroute</code>, <code>ping</code>… <br>
<q>basta, et qu&rsquo;on me fiche la paix !</q></p>
<p>D&rsquo;autres disent, oui, mais c&rsquo;est quand même bien pratique d&rsquo;utiliser de
telles commandes, sauf que…</p>
<p>Le but évident d&rsquo;ICMP est de rapporter les messages d&rsquo;erreurs, d&rsquo;informations
des états, de contrôle, liés à la communication IP d&rsquo;un réseau, dont Internet,
donc, relatifs à la délivrance des paquets IP.</p>
<p>Ce but intéressant a ses défauts : puisque par ce biais-là, toute personne
qui utilise le protocole ICMP peut &ldquo;cartographier&rdquo; l&rsquo;ensemble de votre réseau,
<em>un moindre mal en somme</em>, voire à chercher à attaquer celui-là, par certaines
attaques connues, telles que le déni de service <strong>Smurf</strong>, comme le fameux
&ldquo;<strong>Ping de la Mort</strong>&rdquo; ou tout autre 



















<span lang="fr">DOS <em>(Deni de Service)</em></span>



























































































 existant. <br>
Certaines attaques permettent aussi de s&rsquo;attaquer au protocole TCP, tel
que le service HTTP (attaque <strong>SlowLoris</strong>), et d&rsquo;autres…</p>
<p><q>Froid dans le dos ? <br> Y&rsquo;a de quoi…</q></p>
<hr>
<p>Dans cet article, nous allons apprendre à gérer correctement ICMP, tout
en tenant compte des recommandations faite par des organismes reconnus,
tel l&rsquo;IETF, l&rsquo;IANA, au-travers de différentes RFC, qui seront toutes
nommées.</p>
<h2 id="gérer-icmp">Gérer ICMP</h2>
<h3 id="les-codes-icmp-à-refuser">Les codes ICMP à refuser</h3>
<p>Les codes ci-dessous sont reconnus pour être dépréciés, dangereux, et
donc <strong>à ne plus utiliser</strong> :</p>
<ul>
<li><strong>3/6</strong> - Destination Network Unknown</li>
<li><strong>3/8</strong> - Source Host Isolated</li>
<li><strong>4/0</strong> - Source Quench</li>
<li><strong>15/0</strong> - Information Request Message</li>
<li><strong>16/0</strong> - Information Reply Message</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Attention</strong>: l&rsquo;IANA, autre organisme mondialement reconnu, fait <a href="https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml" rel="external">référence</a>
à la <a href="/fr/sec/firewall/linux-firewall-icmp/#rfc-6633">RFC 6633</a>, à-propos de la <strong>dépréciation de Source Quench</strong>,
et <strong>recommande de loguer de tels paquets et de les supprimer, sans
avertissements (DROP)</strong>.</div>

<p><strong>N&rsquo;hésitons même pas, les messages correspondant doivent ABSOLUMENT être
refusés !</strong></p>
<hr>
<p>L&rsquo;IANA, dans sa <a href="https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml" rel="external">référence</a> à la <strong><a href="/fr/sec/firewall/linux-firewall-icmp/#rfc-6918">RFC 6918</a></strong> considère que les
codes suivants sont dépréciés et donc à filtrer - <em>toute discrétion est laissé
libre à l&rsquo;administrateur de choisir son mode de filtrage</em> - :</p>
<ul>
<li>
<p><strong>6/0</strong> - Alternate Host Address</p>
</li>
<li>
<p><strong>15</strong> - Information Request</p>
</li>
<li>
<p><strong>16</strong> - Information Reply</p>
</li>
<li>
<p><strong>17</strong> - Address Mask Request</p>
</li>
<li>
<p><strong>18</strong> - Address Mask Reply</p>
</li>
<li>
<p><strong>30</strong> - Traceroute</p>
</li>
<li>
<p><strong>31</strong> - Datagram Conversion Error</p>
</li>
<li>
<p><strong>32</strong> - Mobile Host Redirect</p>
</li>
<li>
<p><strong>33</strong> - IPv6 Where-Are-You</p>
</li>
<li>
<p><strong>34</strong> - IPv6 I-Am-Here</p>
</li>
<li>
<p><strong>35</strong> - Mobile Registration Request</p>
</li>
<li>
<p><strong>36</strong> - Mobile Registration Reply</p>
</li>
<li>
<p><strong>37</strong> - Domain Name Request</p>
</li>
<li>
<p><strong>38</strong> - Domain Name Reply</p>
</li>
<li>
<p><strong>39</strong> - SKIP</p>
</li>
</ul>
<p>À vous de choisir, si vous les détruisez… <em>alors, mode parano ?!</em></p>
<p>Quoiqu&rsquo;il en soit, si vous décidez de filtrer le code 30, n&rsquo;oubliez pas
que l&rsquo;utilitaire <strong>traceroute</strong> est capable de fonctionner sur les protocoles
UDP:53, TCP:80, voire d&rsquo;imiter le code ICMP:8/0 !</p>
<h3 id="les-codes-icmp-à-limiter">Les codes ICMP à limiter</h3>
<p>Les recommandations sont de limiter, en entrée et en sortie de machine :</p>
<ul>
<li>le code <strong>0/0</strong> - Echo Reply Message - <em>(la fameuse réponse au Ping : le Pong)</em></li>
<li>tous les autres codes de <strong>type 3</strong> - Destination Unreachable -
<ul>
<li>sauf un traitement légèrement particulier pour le <strong>3/7</strong> - Destination
Host Unknown - à limiter en sortie et ignorer en entrée.</li>
</ul>
</li>
<li>tous les codes <strong>5</strong> - Redirect</li>
<li>le code <strong>8/0</strong> - Echo Message - <em>(la fameuse commande Ping)</em></li>
<li>le code <strong>9/0</strong> - Router Advertisement Message</li>
<li>le code <strong>10/0</strong> - Router Solicitation Message</li>
<li>tous les codes <strong>11</strong> - Time Exceeded - <em>(Utile pour la commande <code>traceroute</code>,
ainsi que le code <strong>30/0</strong> d&rsquo;ailleurs)</em></li>
<li>tous les codes <strong>12</strong> - Parameter Problem</li>
<li>le code <strong>13/0</strong> - Timestamp Message</li>
<li>le code <strong>14/0</strong> - Timestamp Reply Message</li>
<li>le code <strong>17/0</strong> - Address Mask Request</li>
<li>le code <strong>18/0</strong> - Address Mask Reply</li>
</ul>
<p>Pour limiter, dans le contexte d&rsquo;une machine Linux, on utilisera l&rsquo;option
<code>match limit</code> avec <strong>iptables</strong>, tout simplement…</p>
<h2 id="exemples">Exemples</h2>
<h3 id="icmp-en-mode-parano">ICMP en mode parano</h3>
<p>En mode parano, vous pouvez très bien ouvrir :</p>
<ul>
<li>en sortie le code 8/0,</li>
<li>et en entrée le code 0/0 relatif à la sortie, pour que vous vous puissiez
pinguer…</li>
<li>et empêcher les autres d&rsquo;en faire autant !</li>
<li>Puis de supprimer tous les autres codes…</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>iptables -A INPUT -p icmp --icmp-type echo-reply -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -m limit --limit 3/s --limit-burst <span style="color:#f99b15">7</span> -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -m limit --limit 3/s --limit-burst <span style="color:#f99b15">7</span> -j ACCEPT
</span></span><span style="display:flex;"><span>iptables -A INPUT -p icmp -j DROP
</span></span><span style="display:flex;"><span>iptables -A OUTPUT -p icmp -j DROP
</span></span></code></pre></div><h3 id="icmp-filtré-limité">ICMP filtré, limité</h3>
<p>Voici, pour l&rsquo;exemple, basé sur la compréhension des recommandations IETF,
des règles ICMP filtrées, limitées ; puis de rejeter tous les autres codes,
avec le message <code>icmp-host-prohibited</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/sbin/iptables -A INPUT -i ethX -p icmp -m limit --limit 3/s --limit-burst <span style="color:#f99b15">7</span> -j icmp4in
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m conntrack --ctstate INVALID -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">0</span> -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Echo reply&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Destination Net Unreachable&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/1 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Destination Host Unreachable&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/3 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Destination Port Unreachable&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/4 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP PathMTU Discovery&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/6 -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 3/8 -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">4</span> -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">5</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Redirect mssg&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 8/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Echo mssg&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 9/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Router Advertisement Message&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 10/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Router Solicitation Message&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">11</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Time exceeded&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">12</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Param pb&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 13/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Timestamp Message&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 14/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Timestamp Reply Message&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">15</span> -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">16</span> -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 17/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Address Mask Request&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type 18/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Address Mask Reply&#34;</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -m icmp --icmp-type <span style="color:#f99b15">30</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT -m comment --comment <span style="color:#48b685">&#34;ICMP Traceroute&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># REJECT Others</span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4in -p icmp -j REJECT --reject-with icmp-host-prohibited
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A OUTPUT -o ethX -p icmp -m limit --limit 3/s --limit-burst <span style="color:#f99b15">7</span> -j icmp4out
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m conntrack --ctstate INVALID -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">0</span> -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/1 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/3 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/4 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/6 -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/7 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 3/8 -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 4/0 -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">5</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 8/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 9/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 10/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">11</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">12</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 13/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 14/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">15</span> -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">16</span> -j DROP
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 17/0 -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type 18/0 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -m icmp --icmp-type <span style="color:#f99b15">30</span> -m conntrack --ctstate NEW,RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>/sbin/iptables -A icmp4out -p icmp -j REJECT --reject-with icmp-host-prohibited
</span></span></code></pre></div><h2 id="documentation">Documentation</h2>
<h3 id="ietf">IETF</h3>
<p>L&rsquo;IETF est un organisme connu, reconnu qui écrit beaucoup de documents techniques,
dont le propos est d&rsquo;améliorer la technicité, la sécurité des usages liés à Internet.</p>
<p>Et, bien-sûr certains documents existants insistent sur le fait de filtrer
ICMP, voire ICMPv6 - relatif à IPv6, tels que :</p>
<ul>
<li>la <strong><a href="/fr/sec/firewall/linux-firewall-icmp/#rfc-4890">RFC 4890</a></strong></li>
<li>la <strong><a href="/fr/sec/firewall/linux-firewall-icmp/#rfc-5927">RFC 5927</a></strong></li>
<li>le <span lang="en"><a href="https://tools.ietf.org/html/draft-ietf-opsec-icmp-filtering-04" rel="external">draft ICMP filtering</a></span></li>
<li>le <span lang="en"><a href="https://tools.ietf.org/id/draft-ietf-v6ops-icmpv6-filtering-recs-02.txt" rel="external">draft ICMPv6 filtering</a></span></li>
</ul>
<p>Ces documents tous intéressants, certains sont vieux, d&rsquo;autres récents,
ont pour propos de réfléchir sérieusement à la sécurité à mettre en place
autour du protocole ICMP.</p>
<p>Le document de travail relatif au filtrage d&rsquo;ICMP aborde l&rsquo;ensemble des
protocoles IPv4 et IPv6 et explique quelles sont les attaques possibles,
et donnent des recommandations utiles, qui vont du refus du paquet à la
limitation des autres.</p>
<p>Clairement certains codes de messages qui sont absolument à bloquer,
refuser, tels que le code ICMP 4/0 alias &ldquo;<strong>Source Quench</strong>&rdquo; qui est
explicitement déprécié, à ne plus utiliser, mais ce n&rsquo;est pas le seul !</p>
<hr>
<p>
<h3 id="rfc-4890">RFC 4890</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc4890" title="RFC 4890 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc4890" title="RFC 4890 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc4890.txt" title="RFC 4890 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc4890.html" title="RFC 4890 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc4890.txt.pdf" title="RFC 4890 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc4890.txt" title="RFC 4890 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-5927">RFC 5927</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc5927" title="RFC 5927 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc5927" title="RFC 5927 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc5927.txt" title="RFC 5927 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc5927.html" title="RFC 5927 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc5927.txt.pdf" title="RFC 5927 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc5927.txt" title="RFC 5927 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-6633">RFC 6633</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc6633" title="RFC 6633 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc6633" title="RFC 6633 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc6633.txt" title="RFC 6633 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc6633.html" title="RFC 6633 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc6633.txt.pdf" title="RFC 6633 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc6633.txt" title="RFC 6633 : au format Text">TXT</a>
	</dd>
</dl>


<h3 id="rfc-6918">RFC 6918</h3>
<dl class="rfc">
	<dt>IETF Tools</dt>
	<dd>
		<a href="https://tools.ietf.org/html/rfc6918" title="RFC 6918 : au format HTML">HTML</a>,
		<a href="https://tools.ietf.org/pdf/rfc6918" title="RFC 6918 : au format PDF">PDF</a>,
		<a href="https://tools.ietf.org/rfc/rfc6918.txt" title="RFC 6918 : au format Text">TXT</a>
	</dd>
	<dt>RFC Editor</dt>
	<dd>
		<a href="https://www.rfc-editor.org/rfc/rfc6918.html" title="RFC 6918 : au format HTML">HTML</a>,
		<a href="https://www.rfc-editor.org/rfc/pdfrfc/rfc6918.txt.pdf" title="RFC 6918 : au format PDF">PDF</a>,
		<a href="https://www.rfc-editor.org/rfc/rfc6918.txt" title="RFC 6918 : au format Text">TXT</a>
	</dd>
</dl>
</p>
<h3 id="wikipedia">Wikipedia</h3>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/Attaque_par_d%c3%a9ni_de_service#Smurfing" title="Article Wikipédia : Attaque_par_déni_de_service#Smurfing">Attaque_par_déni_de_service#Smurfing <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://fr.wikipedia.org/wiki/Ping_de_la_mort" title="Article Wikipédia : Ping_de_la_mort">Ping_de_la_mort <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
<li><a href="https://fr.wikipedia.org/wiki/Slowloris" title="Article Wikipédia : Slowloris">Slowloris <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Filtrer de manière sécurisé le protocole ICMP sous Linux : exemples avec le parefeu Iptables]]></summary>
        <published>2017-07-26T21:03:54+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:85bfc62f-866b-f8ea-d26d-1226ae05b79c</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/chkrootkit-suckit-rootkit-sbin-init-infected/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Chkrootkit : Suckit Rootkit Sbin Init Infected</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="chkrootkit" scheme="http://doc.huc.fr.eu.org/fr/tags/chkrootkit/" />
        <category term="suckit" scheme="http://doc.huc.fr.eu.org/fr/tags/suckit/" />
        <category term="init" scheme="http://doc.huc.fr.eu.org/fr/tags/init/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="intrusion" scheme="http://doc.huc.fr.eu.org/fr/tags/intrusion/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Chkrootkit émet cette alerte :
<q>Searching for Suckit rootkit&hellip; Warning: /sbin/init INFECTED</q> !</p>
<p><strong>Déjà, si votre installation est fraîche, ne paniquez pas ; de toute façon,
cela ne sert jamais à rien !</strong></p>
<h2 id="analyse">Analyse</h2>
<p>Déjà, si j&rsquo;ai bien compris, il y a de grandes probabilités pour que ce soit
un faux positif, qui traîne depuis longtemps - cf : le bogue #<a href="https://bugs.launchpad.net/cyborg/+bug/454566" rel="external">454566</a> -,
et qui semble être résolu avec la version 0.50.</p>
<p>Mais avant de courir pour mettre-à-jour votre version, analysons ce qui peut l&rsquo;être !</p>
<p>Ensuite, si j&rsquo;ai bien compris quand la machine est infectée par ce rootkit
Suckit, elle place la chaîne <strong>HOME</strong> dans le répertoire <code>/sbin/init</code>.</p>
<p>⇒ Une première analyse commence avec la commande suivante : <br>
<code>$ ls -li /sbin/init /sbin/telinit</code> <br>
<code>130357 -rwxr-xr-x 1 root root 265848 juil. 18  2014 /sbin/init</code> <br>
<code>130426 -rwxr-xr-x 1 root root 104728 juil. 18  2014 /sbin/telinit</code> <br></p>
<p>Si vous ressortez le même résultat, c&rsquo;est déjà bon signe…</p>
<p>⇒ Continuons l&rsquo;analyse et vérifions la présence de chaîne <strong>HOME</strong> : <br>
<code>$ strings /sbin/init | grep -E HOME</code></p>
<p>Normalement, il ne devrait RIEN avoir dans ce répertoire !</p>
<p>Mais dans le cas de distribution récente, telle que depuis Ubuntu (et assimilée) Trusty,
vous aurez exactement cette sortie, qui semble tout autant normale : <br>
<code>$ strings /sbin/init | egrep HOME</code> <br>
<code>XDG_CACHE_HOME</code> <br>
<code>XDG_CONFIG_HOME</code> <br></p>
<p>Pas de panique : apparemment, ce sont des <a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html" rel="external">spécifications liées au standard FreeDesktop</a>…</p>
<p>⇒ Continuons l&rsquo;analyse, avec la commande : <br>
<code># cat /proc/1/maps | grep -E &quot;init.&quot;</code></p>
<p><strong>Normalement, aucun retour ne devrait être fait !</strong></p>
<p>⇒ Vérifions la somme md5 du binaire <strong>init</strong>, puis comparons-la avec l&rsquo;officielle : <br>
<code>$ md5sum /sbin/init</code> <br>
<code>249b19aaa268143c3a0b3d6aa9faa070  /sbin/init</code> <br>
<code>$ grep &quot;sbin/init$&quot; /var/lib/dpkg/info/upstart.md5sums</code> <br>
<code>249b19aaa268143c3a0b3d6aa9faa070  sbin/init</code> <br></p>
<p>Si les sommes sont similaires, c&rsquo;est un autre bon signe…</p>
<p>L&rsquo;autre moyen - <strong>à préférer</strong> - est de :</p>
<ul>
<li>télécharger le packet <strong>upstart</strong> de votre distribution - <em>vérifier que
vous télécharger bien l&rsquo;exacte version correspondante !</em> -,</li>
<li>l&rsquo;extraire,</li>
<li>et faire une comparaison des sommes ; <strong>le mieux étant de la faire avec <code>sha256sum</code>, voire <code>sha512sum</code></strong> !</li>
</ul>
<p>⇒ Histoire d&rsquo;être ABSOLUMENT sûr que vous avez bien à faire à
ce fameux faux positif, exécutez la suite de commande, ci-dessous :
<code>$ cd /sbin</code> <br>
<code>$ ls -l init</code> <br>
<code>-rwxr-xr-x 1 root root 265848 juil. 18  2014 init</code> <br></p>
<p>Si vous voyez bien <code>1</code>, c&rsquo;est bon !</p>
<p>⇒ finissons-en avec :
<code>$ ln /sbin/init /sbin/init2</code> <br>
<code>$ ls -l init</code> <br>
<code>-rwxr-xr-x 2 root root 265848 juil. 18  2014 init</code> <br></p>
<p>Si vous lisez bien <code>2</code>, et non pas <code>1</code>, c&rsquo;est que vous êtes bon ! <br>
Félicitations !!!</p>
<p><em>Pensez à supprimer le lien <code>init2</code>.</em></p>
<hr>
<h3 id="rkhunter">rkhunter</h3>
<p>Une autre manière de vérifier est d&rsquo;exécuter <strong>rkhunter</strong> : <br>
<code>rkhunter --checkall --report-warnings-only</code></p>
<p>Si, à la fin de l&rsquo;analyse, vous n&rsquo;avez rien - <em>ce qui devrait être le cas,
après avoir vérifié comme précédemment</em> - c&rsquo;est que c&rsquo;est vraiment tout bon !</p>
<h2 id="mise-à-jour">Mise à jour</h2>
<p>Si c&rsquo;est possible, mettez-à-jour la version de <strong>chkrootkit</strong> vers la v0.50, minimum !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Que faire en cas de message de chkrootkit : Suckit rootkit... Warning: /sbin/init INFECTED ?]]></summary>
        <published>2017-07-24T21:11:35+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:91d64d58-cf26-db6b-4fca-adcac7b000d4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter-warning-unhide-rb/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter : Warning: /usr/bin/unhide.rb</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="unhide.rb" scheme="http://doc.huc.fr.eu.org/fr/tags/unhide.rb/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>rkhunter</strong> peut parfois poser problème avec ce message d&rsquo;alerte suivant : <br>
<q>Warning: The command &lsquo;/usr/bin/unhide.rb&rsquo; has been replaced by a script: /usr/bin/unhide.rb: Ruby script, ASCII text</q></p>
<h2 id="analyse">Analyse</h2>
<p>⇒ La première chose à s&rsquo;assurer que le binaire en question n&rsquo;a pas été trafiqué,
pour cela, utilisons le binaire <strong>debsums</strong>, tel que : <br>
<em>Bien-sûr, si vous ne l&rsquo;avez pas installé, faites-le… mais c&rsquo;est dommage.</em></p>
<p><code># debsums unhide.rb</code> <br>
<code>/usr/bin/unhide.rb                                                            OK</code> <br>
<code>/usr/share/doc/unhide.rb/changelog.Debian.gz                                  OK</code> <br>
<code>/usr/share/doc/unhide.rb/copyright                                            OK</code> <br>
<code>/usr/share/lintian/overrides/unhide.rb                                        OK</code> <br>
<code>/usr/share/man/man8/unhide.rb.8.gz                                            OK</code> <br></p>
<p>⇒ Maintenant, par acquis de conscience, faites ceci :</p>
<p><code>$ cp /usr/bin/unhide.rb $HOME</code> <br>
<code># apt purge unhide.rb</code> <br>
<code># apt install unhide.rb</code> <br>
<code>$ diff /usr/sbin/unhide.rb ~/unhide.rb</code> <br></p>
<p>Si <strong>diff</strong> ne retourne aucune information, c&rsquo;est que les deux fichiers
en question sont identiques ! <br>
<em>(à moins d&rsquo;avoir eu la malchance d&rsquo;avoir eu le binaire <strong>diff</strong> lui même modifié…)</em></p>
<p>Si tout semble &lsquo;OK&rsquo;, c&rsquo;est que l&rsquo;on a faire face au fameux faux positif
de rkhunter concernant ce binaire ! <br>
<em>ce qui devrait être le cas dans une installation fraîchement exécutée !</em></p>
<p>⇒ Contrôlons les sommes de contrôle différemment :</p>
<p><code>$ md5sum /usr/bin/unhide.rb</code> <br>
<code>b1642389370e283c580de371b61ec3cb  /usr/bin/unhide.rb</code> <br>
<code>$ grep &quot;usr/bin/unhide.rb&quot; /var/lib/dpkg/info/unhide.rb.md5sums</code> <br>
<code>b1642389370e283c580de371b61ec3cb  usr/bin/unhide.rb</code> <br></p>
<hr>
<p>⇒ L&rsquo;autre manière est de :</p>
<ul>
<li>télécharger le binaire <strong>unhide.rb</strong>, depuis le dépôt officiel,</li>
<li>le décompresser et</li>
<li>comparer les sommes avec <code>sha256sum</code>, voire <code>sha512sum</code> ! - <strong>c&rsquo;est même préférable</strong></li>
</ul>
<p>Si les sommes sont identiques, c&rsquo;est tout bon !</p>
<p>Pensez à supprimer le fichier <code>~/unhide.rb</code> que vous avez créé lors de la
copie, précédemment !</p>
<h2 id="configuration">Configuration</h2>
<p>Puisque tout semble bon, modifions le fichier <code>/etc/rkhunter.conf</code>, pour
modifier cette variable : <code>PKGMGR=DPKG</code></p>
<p>Recharger la base de donnée de rkhunter, avec l&rsquo;option <code>--propupd</code>, et
lancez à nouveau le test.</p>
<p>Normalement, l&rsquo;utilitaire <code>unhide.rb</code> devrait correctement être pris en charge…</p>
<p>Si jamais, ce n&rsquo;était pas le cas :</p>
<ul>
<li>vous pouvez décommenter la ligne suivante du fichier rkhunter.conf : <br>
<code>#SCRIPTWHITELIST=/usr/bin/unhide.rb</code> - mais gardez à l&rsquo;esprit que <strong>ce n&rsquo;est pas préférable/recommandable</strong>.</li>
</ul>
<p>Si malgré tout, cela n&rsquo;est pas bon, envisager sérieusement une réinstallation
de votre Linux !!!</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;avis de détection par rkhunter : Warning: /usr/bin/unhide.rb]]></summary>
        <published>2017-07-24T20:42:46+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:7cbcf84d-a9bf-e15a-f0e8-15a221dd6aba</id>
        <link href="http://doc.huc.fr.eu.org/fr/dev/bash/script-convert-optimize-image/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Bash : Convertir et optimiser image jpeg et/ou png</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Bash" scheme="http://doc.huc.fr.eu.org/fr/tags/bash/" />
        <category term="convert" scheme="http://doc.huc.fr.eu.org/fr/tags/convert/" />
        <category term="optimize" scheme="http://doc.huc.fr.eu.org/fr/tags/optimize/" />
        <category term="image" scheme="http://doc.huc.fr.eu.org/fr/tags/image/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ce script a pour but d&rsquo;aider très simplement à convertir, mais surtout
d&rsquo;optimiser des images jpg, des images png, afin de gagner en poids de
l&rsquo;image, pour l&rsquo;intégration de celles-ci dans les sites web. Et donc
de réduire le coût de la bande passante !</p>
<p>Ce script bash de conversion et d&rsquo;optimisation d&rsquo;images jpeg et png,
fonctionne très simplement. Il y a trois options possibles :</p>
<ul>
<li>l&rsquo;option <code>jpg2jpg</code> dont le but est d&rsquo;optimiser une image jpeg après une conversion 
à une qualité, ayant le ratio 70%. <br>
   Le gain est conséquent, de l&rsquo;ordre du facteur 3 !</li>
<li>l&rsquo;option <code>jpg2png</code> permet de convertir l&rsquo;image jpeg en image png, puis d&rsquo;optimiser 
ladite image png. <br>
   <span class="attention">Attention, explosion du poids !</span></li>
<li>l&rsquo;option <code>png2png</code> génère l&rsquo;optimisation d&rsquo;image png.</li>
</ul>
<p>Pour se servir de ce script de conversion et d&rsquo;optimisation d&rsquo;image
jpeg et/ou d&rsquo;image png, vous devez veillez à avoir les outils suivants
:</p>
<ul>
<li>les outils d&rsquo;ImageMagick qui fournissent l&rsquo;outil de conversion : <code>mogrify</code>.</li>
<li>la librairie jpeg <code>libjpeg</code> qui fournit l&rsquo;outil d&rsquo;optimisation jpeg : <code>jpegtran</code>.</li>
<li>l&rsquo;outil d&rsquo;optimisation png : <code>pngnq</code></li>
<li>le système de fichier virtuel <code>gvfs-bin</code> qui fournit l&rsquo;outil <code>gvfs-info</code>.</li>
</ul>
<p><span class="IMP">Bien évidemment, vous devez veiller à ce que vos images à
traiter soient de qualité originale, des images &lsquo;sources&rsquo; !</span></p>
<h2 id="le-script--convert_image">Le script : convert_image()</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#776e71"># ./convert_image /name_dir/ options</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># options are: &#39;jpg2jpg&#39;, &#39;jpg2png&#39;, &#39;png2png&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># you need ImageMagick tools, libjpeg (jpegtran), gvfs-bin</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  Convert image jpg</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  1/ jpg to jpg, quality 70 and optimize : option jpg2jpg</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  2/ jpg to png : option jp2png</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  3/ png to optimize png : option png2png</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>clear
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  define variables needed</span>
</span></span><span style="display:flex;"><span>declare -a <span style="color:#ef6155">EXTS</span><span style="color:#5bc4bf">=(</span> jpg JPG <span style="color:#5bc4bf">)</span> <span style="color:#776e71"># extension accepted</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>declare -i <span style="color:#ef6155">ARGS</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">2</span> <span style="color:#776e71"># number of arguments accepted declare -i mssg=1 #</span>
</span></span><span style="display:flex;"><span>to display message declare -i <span style="color:#ef6155">cmptr</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#776e71"># compteur declare -a</span>
</span></span><span style="display:flex;"><span>MIME<span style="color:#5bc4bf">[</span>1<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;image/jpeg&#34;</span> <span style="color:#776e71"># mime type jpg declare -a</span>
</span></span><span style="display:flex;"><span>MIME<span style="color:#5bc4bf">[</span>2<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;image/png&#34;</span> <span style="color:#776e71"># mime type png declare -a option=( jpg2jpg</span>
</span></span><span style="display:flex;"><span>jpg2png png2png <span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">IFS</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">$&#39;n&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#  functions needed !</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> convert_image <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    verify_args <span style="color:#ef6155">$1</span> <span style="color:#ef6155">$2</span>
</span></span><span style="display:flex;"><span>    verify_bin
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    create_vars_dir <span style="color:#ef6155">$1</span> <span style="color:#ef6155">$2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#empty_dir $dir_out</span>
</span></span><span style="display:flex;"><span>    empty_dir <span style="color:#ef6155">$dir_out2</span>
</span></span><span style="display:flex;"><span>      
</span></span><span style="display:flex;"><span>    create_dir <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>    create_dir <span style="color:#ef6155">$dir_out2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>     <span style="color:#815ba4">for</span> f in find <span style="color:#ef6155">$1</span> -type f;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>         create_vars_image
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">case</span> <span style="color:#ef6155">$mime</span> in
</span></span><span style="display:flex;"><span>              <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MIME</span>[1]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                  
</span></span><span style="display:flex;"><span>                   <span style="color:#815ba4">case</span> <span style="color:#ef6155">$2</span> in
</span></span><span style="display:flex;"><span>                        <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">option</span>[0]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                             increment
</span></span><span style="display:flex;"><span>                             jpg2jpg
</span></span><span style="display:flex;"><span>                             optimize_jpg
</span></span><span style="display:flex;"><span>                             empty_img_converted <span style="color:#ef6155">$dir_out</span> <span style="color:#ef6155">$ff</span>
</span></span><span style="display:flex;"><span>                        ;;
</span></span><span style="display:flex;"><span>                        <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">option</span>[1]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                             increment
</span></span><span style="display:flex;"><span>                             jpg2png
</span></span><span style="display:flex;"><span>                             optimize_png
</span></span><span style="display:flex;"><span>                        ;;
</span></span><span style="display:flex;"><span>                        *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                             exit
</span></span><span style="display:flex;"><span>                        ;;
</span></span><span style="display:flex;"><span>                   <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>      
</span></span><span style="display:flex;"><span>              ;;
</span></span><span style="display:flex;"><span>      
</span></span><span style="display:flex;"><span>              <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MIME</span>[2]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                   <span style="color:#815ba4">case</span> <span style="color:#ef6155">$2</span> in
</span></span><span style="display:flex;"><span>                        <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">option</span>[2]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                             optimize_png
</span></span><span style="display:flex;"><span>                        ;;
</span></span><span style="display:flex;"><span>                        *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                             exit
</span></span><span style="display:flex;"><span>                        ;;
</span></span><span style="display:flex;"><span>                   <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>              ;;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>              *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                   exit
</span></span><span style="display:flex;"><span>              ;;
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> create_dir <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span>! -d <span style="color:#ef6155">$1</span><span style="color:#5bc4bf">](</span>!_-d_<span style="color:#ef6155">$1</span><span style="color:#5bc4bf">)</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;*** Create directory </span><span style="color:#ef6155">$1</span><span style="color:#48b685"> ***&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>         mkdir <span style="color:#ef6155">$1</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> create_vars_dir <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">dir_out</span><span style="color:#5bc4bf">=</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;converted/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;*** Create variables needed for </span><span style="color:#ef6155">$2</span><span style="color:#48b685"> : dir_out ***&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">dir_out2</span><span style="color:#5bc4bf">=</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;optim_jpg/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;*** Create variables needed for </span><span style="color:#ef6155">$2</span><span style="color:#48b685"> : dir_out2 ***&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> create_vars_image <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>     <span style="color:#ef6155">dir</span><span style="color:#5bc4bf">=</span>dirname <span style="color:#ef6155">$f</span>
</span></span><span style="display:flex;"><span>     <span style="color:#ef6155">ff</span><span style="color:#5bc4bf">=</span>basename <span style="color:#ef6155">$f</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">ext</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">${</span><span style="color:#ef6155">ff</span>:(-3)<span style="color:#f99b15">}</span>;
</span></span><span style="display:flex;"><span>     <span style="color:#ef6155">name</span><span style="color:#5bc4bf">=</span>basename <span style="color:#ef6155">$f</span> .<span style="color:#ef6155">$ext</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#length=${#ff}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#name=${ff:0:$length-4};</span>
</span></span><span style="display:flex;"><span>     <span style="color:#ef6155">mime</span><span style="color:#5bc4bf">=</span>gvfs-info --attributes<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;standard::content-type&#34;</span> <span style="color:#ef6155">$f</span> | grep <span style="color:#48b685">&#34;standard::content-type&#34;</span> | cut -c27-
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> empty_dir <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$1</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span>-d <span style="color:#ef6155">$1</span><span style="color:#5bc4bf">](</span>-d_<span style="color:#ef6155">$1</span><span style="color:#5bc4bf">)</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>              cd <span style="color:#ef6155">$1</span>
</span></span><span style="display:flex;"><span>              rm *
</span></span><span style="display:flex;"><span>              <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;~~~ Dir </span><span style="color:#ef6155">$1</span><span style="color:#48b685"> empty! ~~~&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>              cd ..
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> empty_img_converted <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$1</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span>-d <span style="color:#ef6155">$1</span><span style="color:#5bc4bf">](</span>-d_<span style="color:#ef6155">$1</span><span style="color:#5bc4bf">)</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>              <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span><span style="color:#ef6155">$2</span><span style="color:#5bc4bf">](</span><span style="color:#ef6155">$2</span><span style="color:#5bc4bf">)</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>                   unlink <span style="color:#ef6155">$1$2</span>;
</span></span><span style="display:flex;"><span>                   <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; 3/ Img </span><span style="color:#ef6155">$ff</span><span style="color:#48b685"> deleted in dir </span><span style="color:#ef6155">$1</span><span style="color:#48b685"> !&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>              <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> increment <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">((</span> cptr++ <span style="color:#5bc4bf">))</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$cptr</span><span style="color:#48b685"> :: Image </span><span style="color:#ef6155">$ff</span><span style="color:#48b685"> { Mime Type: </span><span style="color:#ef6155">$mime</span><span style="color:#48b685"> } to convert&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> jpg2jpg <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    cp <span style="color:#ef6155">$f</span> <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>    cd <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; 1/ Convert image </span><span style="color:#ef6155">$ff</span><span style="color:#48b685"> to quality 70 ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    mogrify -quality 70 <span style="color:#ef6155">$ff</span>
</span></span><span style="display:flex;"><span>             
</span></span><span style="display:flex;"><span>    cd <span style="color:#48b685">&#34;..&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> jpg2png <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; Convert image </span><span style="color:#ef6155">$ff</span><span style="color:#48b685"> to PNG ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    mogrify -format png <span style="color:#ef6155">$f</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> optimize_jpg <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; 2/ Optimize image </span><span style="color:#ef6155">$ff</span><span style="color:#48b685"> with jpegtran ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    jpegtran -optimize -progressive -perfect -copy all <span style="color:#ef6155">$dir_out$ff</span> &gt; <span style="color:#ef6155">$dir_out2$ff</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> optimize_png <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; Deplace image </span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png to optimize-it! ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#ef6155">$mime</span> in
</span></span><span style="display:flex;"><span>         <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MIME</span>[1]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>              mv <span style="color:#ef6155">$1$name</span><span style="color:#48b685">&#34;.png&#34;</span> <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>         ;;
</span></span><span style="display:flex;"><span>         <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">MIME</span>[2]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span><span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>              cp <span style="color:#ef6155">$1$name</span><span style="color:#48b685">&#34;.png&#34;</span> <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>         ;;
</span></span><span style="display:flex;"><span>         *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>              exit
</span></span><span style="display:flex;"><span>         ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    cd <span style="color:#ef6155">$dir_out</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; Optimize image </span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png with pngnq ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    pngnq -vf -s1 <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; delete </span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    unlink <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">mssg</span> <span style="color:#5bc4bf">==</span> 1 <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;=&gt; Rename image PNG temporary in name </span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png ...&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    mv <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$name</span><span style="color:#48b685">-nq8.png&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$name</span><span style="color:#48b685">.png&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#echo &#34;=&gt; Optimize image PNG {$name.png} with optipng ...&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#776e71">#optipng -o7 &#34;$name.png&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    cd <span style="color:#48b685">&#34;..&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> status <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">case</span> <span style="color:#ef6155">$1</span> in
</span></span><span style="display:flex;"><span>         0<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">txt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;*** More argument; just call the script as: ./convert_image /name_dir/ &#39;jpg2jpg|jpg2png|png2png&#39; ***&#34;</span> ;;
</span></span><span style="display:flex;"><span>         1<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">txt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;*** Directory needed! ***&#34;</span> ;;
</span></span><span style="display:flex;"><span>         2<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">txt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;*** argument &#39;jpg2jpg&#39;, &#39;jpg2png&#39; or &#39;png2png&#39; needed! ***&#34;</span> ;;
</span></span><span style="display:flex;"><span>         3<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">txt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;*** bad argument: argument is &#39;jpg2jpg&#39;, &#39;jpg2png&#39; or &#39;png2png&#39;! ***&#34;</span> ;;
</span></span><span style="display:flex;"><span>         4<span style="color:#5bc4bf">)</span> <span style="color:#ef6155">txt</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;*** ERROR: Script stop here because the bin ***</span><span style="color:#ef6155">$2</span><span style="color:#48b685">*** is not installed; in </span><span style="color:#ef6155">$3</span><span style="color:#48b685">... ***&#34;</span> ;;
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> test -n <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$txt</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span> echo <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$txt</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    exit
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> verify_args <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> test -z <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$1</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span> status 1; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span>! -d <span style="color:#ef6155">$1</span><span style="color:#5bc4bf">](</span>!_-d_<span style="color:#ef6155">$1</span><span style="color:#5bc4bf">)</span>; <span style="color:#815ba4">then</span> exit; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> test -z <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$2</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">then</span> status 2; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">$2</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;jpg2jpg&#34;</span> <span style="color:#5bc4bf">||</span> <span style="color:#ef6155">$2</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;jpg2png&#34;</span> <span style="color:#5bc4bf">||</span> <span style="color:#ef6155">$2</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;png2png&#34;</span> <span style="color:#5bc4bf">))</span>; <span style="color:#815ba4">then</span> status 3; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">function</span> verify_bin <span style="color:#5bc4bf">()</span> <span style="color:#5bc4bf">{</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    bin<span style="color:#5bc4bf">[</span>1<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;jpegtran&#34;</span>
</span></span><span style="display:flex;"><span>    bin<span style="color:#5bc4bf">[</span>2<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;mogrify&#34;</span>
</span></span><span style="display:flex;"><span>    bin<span style="color:#5bc4bf">[</span>3<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;gvfs-info&#34;</span>
</span></span><span style="display:flex;"><span>    get<span style="color:#5bc4bf">[</span>1<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;libjpeg&#34;</span>
</span></span><span style="display:flex;"><span>    get<span style="color:#5bc4bf">[</span>2<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;ImageMagick Tools&#34;</span>
</span></span><span style="display:flex;"><span>    get<span style="color:#5bc4bf">[</span>3<span style="color:#5bc4bf">]=</span><span style="color:#48b685">&#34;gvfs-bin&#34;</span>
</span></span><span style="display:flex;"><span>      
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">for</span> <span style="color:#5bc4bf">((</span> <span style="color:#ef6155">i</span><span style="color:#5bc4bf">=</span>1 ; i&lt;<span style="color:#5bc4bf">=</span>3 ; i++ <span style="color:#5bc4bf">))</span> <span style="color:#815ba4">do</span>
</span></span><span style="display:flex;"><span>         <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[[</span> ! -e <span style="color:#48b685">&#34;/usr/bin/</span><span style="color:#f99b15">${</span><span style="color:#ef6155">bin</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]]</span>; <span style="color:#815ba4">then</span> status 4 <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">bin</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span> <span style="color:#48b685">&#34;</span><span style="color:#f99b15">${</span><span style="color:#ef6155">get</span>[<span style="color:#ef6155">$i</span>]<span style="color:#f99b15">}</span><span style="color:#48b685">&#34;</span>; <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">done</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># appel to the function convert_image</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$#</span> -ne <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$ARGS</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    status <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">else</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    convert_image <span style="color:#ef6155">$1</span> <span style="color:#ef6155">$2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span></code></pre></div><h2 id="utilisation">Utilisation</h2>
<p>Il ne reste plus qu&rsquo;à l&rsquo;utiliser ainsi :</p>
<p><code>$ chmod 0700 convert_image $ ./convert_image /name_dir/ option</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Script Bash de conversion d&#39;image jpeg ou png afin de les optimiser voire les minimiser]]></summary>
        <published>2017-07-24T16:56:42+01:00</published>
        <updated>2017-07-28T12:34:17+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:9e26c135-a6c3-a928-538e-67605afe955b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter-warning-file-immutable-bit-set/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter : Warning: File has the immutable-bit set</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="immutable" scheme="http://doc.huc.fr.eu.org/fr/tags/immutable/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Rkhunter émet cet avis : <br>
<q>Warning: File &lsquo;/sbin/xyz&rsquo; has the immutable-bit set.</q>
et, il le fait sur plusieurs fichiers !</p>
<p>Ahahhh, petit malin, je vous y prend, vous avez utilisez l&rsquo;

<a class="inside" href="/fr/sec/linux/chattr/" title="Lien interne vers l&#39;article : 'Durcir Linux : Utiliser chattr'">outil chattr avec l&#39;option `-I`</a>
,
n&rsquo;est-ce pas ?! <br>
Tant mieux… sinon, vous avez peut-être un petit problème !</p>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration <code>/etc/rkhunter.conf</code> renferme une option
à-priori utile : <code>IMMUTABLE_SET=0</code> !</p>
<p>Sauf qu&rsquo;une fois activée, lors d&rsquo;une vérification, ce sont les quelques binaires
qui ne peuvent avoir l&rsquo;option <code>immutable</code>, qui vont recevoir ladite complainte.</p>
<p><q>C&rsquo;est un peu l&rsquo;histoire du serpent qui se mort la queue</q>, n&rsquo;est-ce pas !</p>
<p>Puisque vous utilisez l&rsquo;option <code>I</code> du binaire <code>chattr</code>, modifiez le fichier
<code>crontab</code> relatif à rkhunter…</p>
<p>Le fichier <code>/etc/default/rkhunter</code> nous informe de ceci :</p>
<pre tabindex="0"><code>:$ cat /etc/default/rkhunter
# Defaults for rkhunter automatic tasks
# sourced by /etc/cron.*/rkhunter and /etc/apt/apt.conf.d/90rkhunter
#
# This is a POSIX shell fragment
#
(…)
</code></pre><p>Nous savons que lors de l&rsquo;installation, il se crée un fichier de cron,
dans <code>/etc/crond.daily/rkhunter</code> - <em>vérifiez votre cas</em> - ouvrons-le pour
le modifier ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">RKHUNTER</span><span style="color:#5bc4bf">=</span>/usr/bin/rkhunter
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>test -x <span style="color:#ef6155">$RKHUNTER</span> <span style="color:#5bc4bf">||</span> exit <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#add by me</span>
</span></span><span style="display:flex;"><span>/repertoire/chattr_sys false
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># source our config</span>
</span></span><span style="display:flex;"><span>. /etc/default/rkhunter
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$NICE</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">NICE</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -z <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$RUN_CHECK_ON_BATTERY</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">RUN_CHECK_ON_BATTERY</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;false&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Do not run daily check if running on battery except if explicitely allowed</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -x /usr/bin/on_ac_power &gt;/dev/null 2&gt;&amp;<span style="color:#f99b15">1</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>    on_ac_power &gt;/dev/null 2&gt;&amp;<span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">[</span> <span style="color:#ef6155">$?</span> -eq <span style="color:#f99b15">1</span> -a <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$RUN_CHECK_ON_BATTERY</span><span style="color:#48b685">&#34;</span> !<span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;true&#34;</span> <span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">&amp;&amp;</span> exit <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">case</span> <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$CRON_DAILY_RUN</span><span style="color:#48b685">&#34;</span> in
</span></span><span style="display:flex;"><span>     <span style="color:#5bc4bf">[</span>YyTt<span style="color:#5bc4bf">]</span>*<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ef6155">OUTFILE</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">`</span>mktemp<span style="color:#48b685">`</span> <span style="color:#5bc4bf">||</span> exit <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>        /usr/bin/nice -n <span style="color:#ef6155">$NICE</span> <span style="color:#ef6155">$RKHUNTER</span> --cronjob --report-warnings-only --appendlog &gt; <span style="color:#ef6155">$OUTFILE</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> <span style="color:#5bc4bf">[</span> -s <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$OUTFILE</span><span style="color:#48b685">&#34;</span> -a -n <span style="color:#48b685">&#34;</span><span style="color:#ef6155">$REPORT_EMAIL</span><span style="color:#48b685">&#34;</span> <span style="color:#5bc4bf">]</span>; <span style="color:#815ba4">then</span>
</span></span><span style="display:flex;"><span>          <span style="color:#5bc4bf">(</span>
</span></span><span style="display:flex;"><span>            echo <span style="color:#48b685">&#34;Subject: [rkhunter] </span><span style="color:#815ba4">$(</span>hostname -f<span style="color:#815ba4">)</span><span style="color:#48b685"> - Daily report&#34;</span>
</span></span><span style="display:flex;"><span>            echo <span style="color:#48b685">&#34;To: </span><span style="color:#ef6155">$REPORT_EMAIL</span><span style="color:#48b685">&#34;</span>
</span></span><span style="display:flex;"><span>            echo <span style="color:#48b685">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>            cat <span style="color:#ef6155">$OUTFILE</span>
</span></span><span style="display:flex;"><span>          <span style="color:#5bc4bf">)</span> | /usr/sbin/sendmail <span style="color:#ef6155">$REPORT_EMAIL</span>
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">fi</span>
</span></span><span style="display:flex;"><span>        rm -f <span style="color:#ef6155">$OUTFILE</span>
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>      *<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>       exit <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>       ;;
</span></span><span style="display:flex;"><span><span style="color:#815ba4">esac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#add by me :</span>
</span></span><span style="display:flex;"><span>/repertoire/chattr_sys true
</span></span></code></pre></div><p>Résultat, lors de la future vérification planifiée de l&rsquo;outil rkhunter,
il exécutera votre script lié à l&rsquo;usage de chattr… en désactivant d&rsquo;abord,
l&rsquo;option <code>immutable</code>, puis fera son boulot, et pour finir réactivera l&rsquo;option.</p>
<p>Si c&rsquo;est vous qui l&rsquo;exécutez, pensez d&rsquo;abord à désactiver… puis à réactiver
votre protection !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre l&#39;avis de détection par rkhunter : Warning: File has the immutable-bit set]]></summary>
        <published>2017-07-24T17:21:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b58a4bb7-72bd-9fb1-26e9-7bc130c9de33</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/apt-errors/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: APT: E:</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="apt" scheme="http://doc.huc.fr.eu.org/fr/tags/apt/" />
        <category term="erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Votre outil apt(-get) vous restitue le message suivant, lors d&rsquo;une mise-à-jour :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>E: Malformed Description-md5 line; doesn<span style="color:#ef6155">&#39;</span>t have the required length !
</span></span></code></pre></div><p>L&rsquo;astuce est la suivante - <em>à faire en mode console, avec vos droits
admins, bien sûr</em> - :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>:# apt-get clean
</span></span><span style="display:flex;"><span>:# cd /var/lib/apt
</span></span><span style="display:flex;"><span>:# mv lists lists.old
</span></span><span style="display:flex;"><span>:# mkdir -p lists/partial
</span></span><span style="display:flex;"><span>:# apt-get clean
</span></span><span style="display:flex;"><span>:# apt-get update
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Debian : Résoudre l&#39;erreur &#39;Malformed MD5 line&#39; pour l&#39;outil apt]]></summary>
        <published>2017-07-23T23:24:04+01:00</published>
        <updated>2018-10-11T21:33:04+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:837ae20e-c53b-da55-c763-1c9ff1e19537</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-usage-securise/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : Du bon usage sécurisé</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ou, comment titrer autrement que : <strong>De meilleures pratiques GPG/PGP</strong> !</p>
<p>Je ne parlerais pas de comment créer une clé GPG pour communiquer de
manière chiffrée ; il existe de très bons guides/tutoriels qui le
font très bien, et vraiment mieux que ce que je ne pourrais le faire :</p>
<ul>
<li>Le guide de l&rsquo;<strong><a href="https://emailselfdefense.fsf.org/fr/index.html" rel="external">Autodéfense courriel</a></strong> -
par la FSF…</li>
<li>Le tutoriel &ldquo;<strong><a href="https://support.mozilla.org/fr/kb/signature-numerique-et-chiffrement-des-messages" rel="external">Signature numérique et chiffrement des messages</a></strong> - Assistance de Thunderbird&rdquo; - par Mozilla.</li>
<li>Le guide des <strong><a href="https://help.riseup.net/fr/security/message-security/openpgp/best-practices" rel="external">bonnes pratiques pour l&rsquo;utilisation d&rsquo;OpenPGP</a></strong> -
par RiseUp</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Pour pouvoir utiliser correctement gpg, il faut installer non seulement
cet outil, mais vous avez besoin d&rsquo;autres outils, tels que :
<code>gnupg gnupg-curl hopenpgp-tools parcimonie openssl</code></p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Certains de ces outils ne sont disponibles que sous Linux… tels <code>hopenpgp-tools</code>,
<code>parcimonie</code>. <br>
Vous ne les trouverez pas nativement sous OpenBSD, ni en package, ni en ports !</p>
<p>Du fait d&rsquo;installer l&rsquo;outil <code>parcimonie</code>, il est <strong>IMPÉRATIF</strong> de ne plus utiliser l&rsquo;option
<code>--refresh-keys</code> de GPG… <br>
<strong>parcimonie</strong> le fera de la manière convenable et surtout sécurisé !</p>
</div>

<h3 id="certificat-sks">Certificat SKS</h3>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Il n&rsquo;est plus recommandé d&rsquo;utiliser le certificat des serveurs SKS ;
mais de se fier qu&rsquo;au seul serveur vraiment sécurisé du projet openpgp,
à savoir : <code>keys.openpgp.org</code>.</div>

<h2 id="configuration">Configuration</h2>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Hormis le fait d&rsquo;avoir IMPÉRATIVEMENT son outil GPG/PGP à jour, afin d&rsquo;éviter
les failles de sécurité, il est recommandé de ne plus utiliser dans aucun
fichier toutes les options <code>keyserver-*</code>.</p>
<p>La seule option <code>keyserver</code> à utiliser, doit l&rsquo;être dans le fichier
<code>~/.gnupg/dirmngr.conf</code>,  tel que : <br>
<code>keyserver hkps://keys.openpgp.org</code></p>
</div>

<p>La configuration sous Unix/Linux se fait dans votre dossier personnel :
<code>~/.gnupg/gpg.conf</code></p>
<p>Ajouter ces options :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">keyid-format 0xlong</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">with-fingerprint</span>
</span></span></code></pre></div><ul>
<li>La première impose l&rsquo;usage du format long - <em>sur 64 bits</em> - de l&rsquo;identifiant
de la clé GPG</li>
<li>la deuxième demande à afficher l&rsquo;empreinte, lors de la sortie…</li>
</ul>
<p>Pour améliorer la qualité des clés GPG, il nous faut rajouter les options
suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">cert-digest-algo SHA512</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">personal-digest-preferences SHA512</span>
</span></span></code></pre></div><ul>
<li>La première demande l&rsquo;usage de l&rsquo;algorithme SHA512</li>
<li>la deuxième annonce la liste des algorithmes préférées, ; il sera utilisé du
plus fort au plus faible, le premier trouvé étant utilisé !</li>
<li>la dernière annonce la préférence personnelle.</li>
</ul>
<p>Pour finir, voici d&rsquo;autres options à utiliser, elles aussi, nécessaires :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">keyserver-options include-revoked</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">keyserver-options no-try-dns-srv</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">list-options show-uid-validity</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">verify-options show-uid-validity</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">use-agent</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auto-key-locate local</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">auto-key-locate keyserver</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">fixed-list-mode</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">utf8-strings</span>
</span></span></code></pre></div><p>Je vous renvoie à la documentation du
<a href="http://www.delafond.org/traducmanfr/man/man1/gpg.1.html" rel="external">manpage</a>
pour que vous compreniez la raison de chacune.</p>
<h2 id="les-recommandations">Les Recommandations</h2>
<p>Autrement-dit, les IMPÉRATIFS à ABSOLUMENT tenir compte sont :</p>
<ul>
<li><span class="red">NE PLUS utiliser toutes les options `keyserver`</span>

dans le fichier de configuration principal</li>
<li><span class="red">NE PLUS utiliser l'option `--refresh-keys`</span>
 de
gpg, sauf si vous n&rsquo;avez pas l&rsquo;outil <strong>parcimonie</strong>.</li>
<li><span class="red">NE PAS avoir confiance dans l'identifiant</span>
 d&rsquo;une
clé GPG, qu&rsquo;il soit de format court ou long - <em>le format court est <a href="http://www.asheesh.org/note/debian/short-key-ids-are-bad-news.html" rel="external">faillible</a> ;
le format long pose son lot de <a href="https://www.debian-administration.org/users/dkg/weblog/105" rel="external">problèmes</a> !</em> <br>
<strong>Utilisez l&rsquo;empreinte de clé GPG</strong>…</li>
<li><strong>NE PAS avoir une confiance aveugle dans les clés fournies</strong>, même celles
sur un serveur SKS - efforcez-vous d&rsquo;être en contact régulier avec votre
contact, par téléphone, voire mieux physiquement, pour vous assurer de la
validité de celles-ci ! <br>
Demandez l&rsquo;empreinte de la clé GPG de votre interlocuteur… et signer la clé
dans votre ordinateur.</li>
<li><span class="red">NE PAS utiliser l'algorithme DSA</span>
, préférez RSA !</li>
<li><span class="red">NE PAS utiliser de longueur de clé inférieure à 4096 bits</span>
 -
<em>de toute façon, dans l&rsquo;immédiat, il n&rsquo;est pas supporté de plus fort !</em></li>
<li><span class="red">NE PAS utiliser MD5, SHA1</span>
 ; utilisez un chiffrement
fort tel que SHA256, voire mieux SHA512 - <em>et paramétrez votre configuration
personnelle dans ce sens, ce que nous avons vu plus haut</em>.</li>
<li><strong>Créer vos clés, avec une <span class="red">date d'expiration maximale</span>

à deux ans</strong> - et, utilisez un calendrier pour vous le rappeler !</li>
<li><strong>Éditer vos clés pour ajouter</strong> :
<ul>
<li>une sous-clé de signature,</li>
<li>une photo,</li>
<li>et paramétrer les préférences de hash…</li>
</ul>
</li>
<li><strong>Créer ABSOLUMENT un certificat de révocation</strong>.</li>
</ul>
<h2 id="du-bon-usage-de-gpg--les-empreintes">Du bon usage de GPG : les empreintes</h2>
<p>Donc, nous l&rsquo;avons compris, il est nécessaire/préférable d&rsquo;utiliser l&rsquo;outil GPG
avec les empreintes de clés.</p>
<p>Ce sont les mêmes commandes optionnelles à gpg, mais au lieu de renseigner l&rsquo;email,
l&rsquo;identifiant de clé, on utilisera l&rsquo;empreinte d&rsquo;une clé …</p>
<ul>
<li>Pour télécharger l&rsquo;empreinte d&rsquo;une clé depuis le serveur : <br>
<code>gpg --recv-key 'fingerprint'</code> - <em>simple ou double quotes, c&rsquo;est pareil</em></li>
<li>Pour vérifier l&rsquo;empreinte d&rsquo;une clé GPG : <br>
<code>gpg --fingerprint 'fingerprint'</code></li>
<li>Pour signer une empreinte de clé GPG : <br>
<code>gpg --sign-key 'fingerprint'</code></li>
<li>Pour signer localement une empreinte de clé GPG : <br>
<code>gpg --lsign-key 'fingerprint'</code> - <br>
<strong>ATTENTION : si vous signez localement, vous ne pourrez plus exporter
votre signature !</strong></li>
<li>Pour gérer un fichier : <br>
<code>gpg --with-fingerprint keyfile</code></li>
<li>Pour créer un certificat de révocation à partir de l&rsquo;empreinte : <br>
<code>gpg --output email@domain.tld.rev.asc --gen-revoke 'fingerprint'</code></li>
<li>Etc.</li>
</ul>
<h2 id="du-bon-outil-gpg">Du bon outil GPG</h2>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<p>Ok, nous avons vu comment utiliser openssl, parcimonie, les outils gpg pour nous
assurer de faire les choses proprement, mais tu n&rsquo;as pas parlé du paquet
<code>hopenpgp-tools</code> ! <br>
En effet ;-)</p>
<p>En fait, dans ce paquet-là, il est fourni au moins deux outils que sont <code>hkt</code> et
<code>hokey</code>… assemblés, ils permettent en mode console d&rsquo;avoir la pertinence qu&rsquo;une
clé GPG est bonne à partir de son empreinte - et ils sont très facile à utiliser,
tel que :</p>
<p><code>hkt export-pubkeys 'fingerprint' | hokey lint</code></p>
<p>Les tests corrects sont affichés en <span class="green">vert</span>
. <br>
Tout problème avec la clé vérifiée est affiché en <span class="red">rouge</span>
 ! <br>
Il faut alors IMPÉRATIVEMENT se méfier d&rsquo;une telle clé, voire la régénérer si
c&rsquo;est la vôtre, après avoir configuré votre fichier de configuration personnelle,
avec les recommandations ci-dessus !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>hkt</strong> n&rsquo;est pas compatible avec GPG version &gt;= 2.1, et générera des erreurs,
rendant impossible le traitement !</div>

<hr>
<h3 id="des-logiciels-graphiques">Des logiciels graphiques</h3>
<ul>
<li><a href="https://www.enigmail.net" rel="external">Enigmail</a> - <em>plugin à Thunderbird, ou dédié</em> -</li>
<li><a href="https://www.gnupg.org/related_software/gpa/index.html" rel="external">GPA</a>, …</li>
<li><a href="http://www.rainloop.net" rel="external">Rainloop</a>,</li>
<li><a href="https://roundcube.net" rel="external">Roundcube</a>, …</li>
</ul>
<h3 id="serveurs-de-clés-consultables">Serveurs de clés consultables</h3>
<ul>
<li>Le seul sécurisé est celui du projet OpenGPG : <strong>keys.openpgp.org</strong></li>
</ul>
<p>Et, vous avez bien compris, tout comme moi d&rsquo;ailleurs… on fait une
recherche par … <del>mail, ID</del>, empreinte !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Apprendre à utiliser de manière sécurisée GPG !]]></summary>
        <published>2017-07-23T23:15:46+01:00</published>
        <updated>2020-01-08T19:23:46+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:62d144df-b560-db95-46ab-0910dcb225b7</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/write-failed-broken-pipe/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : Write Failed: broken pipe</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Ahhh, les joies de SSH, n&rsquo;est-ce pas ?!</p>
<ul>
<li>Ce matin, vous vous levez, vous cherchez à vous connecter à votre serveur… <br>
et très rapidement, vous vous faites déconnecter avec ce, <em>pas joli du tout</em>,
message : <code>Write Failed: broken pipe</code>. <br>
Vous vous reconnectez, et rebelote !!!</li>
</ul>
<h2 id="informations">Informations</h2>
<p>Il y a plusieurs raisons possibles à ce genre de déconnexions
intempestives, et fortement désagréables, et aucunes de particulières.</p>
<h2 id="configuration">Configuration</h2>
<p>De fait, il existe trois options SSH à configurer qui permettent
d&rsquo;améliorer sensiblement la tenue de la connexion, dont une
<code>TCPKeepAlive yes</code> qui peut être paramétrée côté serveur et
côté client !</p>
<h3 id="côté-serveur">Côté serveur</h3>
<p>Ouvrez votre fichier <code>/etc/ssh/sshd_config</code>, et rajoutez ces deux options :</p>
<ul>
<li><code>ClientAliveInterval</code> : est le nombre de secondes pendant lequel le serveur
va attendre avant d&rsquo;envoyer un paquet null au client - le but étant de
garder la connexion vivante.</li>
<li><code>ClientAliveCountMax</code> : est la limite donnée à un client pendant lequel il
est autorisé à ne pas donner de réponse, sans se faire déconnecter - sa
valeur par défaut est : <code>3</code></li>
</ul>
<h3 id="côté-client">Côté client</h3>
<p>Ouvrez votre fichier <code>~/.ssh/config</code>, et ajoutez ces deux options
correspondantes :</p>
<ul>
<li><code>ServerAliveInterval</code> : est le nombre de secondes pendant lequel le client va
attendre avant d&rsquo;envoyer un paquet null au serveur - le but étant toujours
de garder vivante la connexion.</li>
<li><code>ServerAliveCountMax</code> : valeur par défaut est de : <code>3</code></li>
</ul>
<h3 id="explications">Explications</h3>
<p>Ces options ont pour propos de <strong>maintenir la connexion en vie</strong> ;
le processus est le suivant :</p>
<ul>
<li>Quand le timing relatif aux options <code>ClientAliveInterval</code> et <code>ServerAliveInterval</code>
est arrivé à son terme, un signal &ldquo;<code>&lt;span lang=&quot;en&quot;&gt;</code>hello-are-you-there<code>&lt;/span&gt;</code>&rdquo;
est envoyé…</li>
<li>le paramétrage des options <code>ClientAliveCountMax</code> et <code>ServerAliveCountMax</code> est
le nombre de fois où ce signal &ldquo;hello&rdquo; va être envoyé.</li>
<li>S&rsquo;il n&rsquo;y a pas de réponse de l&rsquo;un ou de l&rsquo;autre au final, la connexion se
fermera.</li>
</ul>
<p>Le calcul est très simple : <code>ClientAliveInterval</code> x <code>ClientAliveCountMax</code> secondes,
côté serveur, et réciproquement pour les options &ldquo;Server&rdquo;, côté client.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">ATTENTION** : Mettre à <code>0</code> ses options les désactivent !</div>

<hr>
<p>Cela devrait améliorer la situation, mais ne la résout pas forcément !</p>
<p>Très utile avec l&rsquo;usage du fameux projet <a href="http:*www.rutschle.net/tech/sslh.shtml" rel="external">SSLH</a> -
le multiplexeur de connexion HTTPS/SS(H|L)/VPN, etc…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment remédier à l&#39;erreur SSH nommée &#39;Write Failed: broken pipe&#39; !]]></summary>
        <published>2017-07-23T22:30:06+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:65cc5032-3b79-eb90-28c8-b4ab0ba797b8</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/ssh/chroot-directory-fatal/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: SSH : ChrootDirectory fatal: bad ownership or modes for chroot directory</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="ChrootDirectory" scheme="http://doc.huc.fr.eu.org/fr/tags/chrootdirectory/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>S&rsquo;il y a bien un mode qui en fait baver, c&rsquo;est l&rsquo;option
<strong>ChrootDirectory</strong> pour le serveur SSH !</p>
<p>En effet, vous avez défini des utilisateurs qui ont le droit d&rsquo;utiliser</p>
<ul>
<li><em><abbr title="c'est-à-dire">càd</abbr>
 de se connecter</em> - à votre serveur SSH, et
mieux, vous gérez cela finement par des accès de groupe, mais vous tenez
absolument à emprisonner les utilisateurs dans leur répertoire privé, et c&rsquo;est
très bien !</li>
</ul>
<p>Une règle, telle que la suivante devrait permettre d&rsquo;agir ainsi, dans
le fichier de config <code>/etc/ssh/sshd_config</code> :</p>
<pre tabindex="0"><code class="language-ssh" data-lang="ssh">Match group sshusers
    ForceCommand internal-sftp
    ChrootDirectory /chroot/%u
</code></pre>
<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Bien-sûr, votre prison peut-être définie ailleurs, tel que dans le répertoire
<code>$HOME</code>, par exemple ; dans ces cas, adaptez, adaptez, adaptez… <br>
et vérifiez que votre utilisateur fasse bien partie du groupe ssh dédié, que
vous aurez précédemment créé - <em>il se nommera certainement autrement que celui
nommé dans cet exemple <code>sshusers</code></em> :)</div>

<p>Mais, voilà, à chaque tentative de connexions, le serveur SSH vous jette
et vous avertit de l&rsquo;erreur suivante :</p>
<div class="info-quote">
    <p class="is-white-50">Citation :</p>
</div>
<div class="quote">
    <figure>
        <blockquote>
            Feb 12 19:56:30 server sshd[64689]: Accepted password for user from 192.168.xxx.yyy port 40829 ssh2
Feb 12 19:56:30 server sshd[64691]: fatal: bad ownership or modes for chroot directory &ldquo;/chroot/user&rdquo;
        </blockquote>
    </figure>
</div>

<p>Ce qui bloque, ce sont les droits d&rsquo;accès, vers le répertoire prison !</p>
<p>Il faut <span class="red">impérativement que les droits soient attribués à `root`,
et en accès `0755`</span>
…</p>
<p>Puis ensuite créer le répertoire utilisateur, et attribuer les droits à l&rsquo;utilisateur en question</p>
<pre tabindex="0"><code class="language-ssh" data-lang="ssh"># avec les droits administrateurs:
chmod 0755 /chroot
chown root:root /chroot
mkdir /chroot/user_id
chmod 0705 /chroot/user_id
chown user_id:user_id /chroot/user_id
</code></pre><p><strong>Si vous aviez déjà créé les répertoires en question, <span em>vérifiez les
droits d&rsquo;accès et d&rsquo;appartenances utilisateurs</span> !</strong></p>
<p>Voilà, à partir de ce moment-là, vous devriez pouvoir réussir enfin la
connexion ssh.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment emprisonner correctement les utilisateurs SSH !]]></summary>
        <published>2017-07-23T22:17:44+01:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:0a5f7c52-0c64-ba71-80e5-94587651f926</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/nginx-error-502-gateway/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Nginx : Erreur 502 (Bad Gateway)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="502" scheme="http://doc.huc.fr.eu.org/fr/tags/502/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le serveur web nginx affiche une &ldquo;belle page blanche&rdquo; avec la mention
<strong>Error 502: Bad Gateway</strong> !</p>
<p>Vérifiez :</p>
<ol>
<li>que le service php-fpm soit démarré !<br>
<em>C&rsquo;est idiot, en soit, mais si le service n&rsquo;est pas démarré, la connexion
avec le serveur ne se fera pas, et provoquera l&rsquo;erreur 502</em>.</li>
<li>vos écritures dans vos fichiers de configuration nginx, celles liées à php,
voire php-fpm… qu&rsquo;elles soient exactement pareilles !</li>
</ol>
<h2 id="configuration">Configuration</h2>
<h3 id="nginx">nginx</h3>
<p>Les fichiers de configuration sont :</p>
<ul>
<li>
<p><code>/etc/nginx/nginx.conf</code></p>
</li>
<li>
<p>ou <code>/etc/nginx/sites-available/*votre_domaine*.conf</code></p>
</li>
<li>
<p>vérifiez votre déclaration liée à la configuration des fichiers PHP :</p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> ~ <span style="color:#48b685">\.php$</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">fastcgi_pass</span> <span style="color:#48b685">unix:/var/run/votre_domaine.sock</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><ul>
<li>vérifier aussi votre déclaration liée à la configuration <code>status</code>, si nécessaire…</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#815ba4">location</span> <span style="color:#48b685">/status</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span>        <span style="color:#48b685">fastcgi_pass</span> <span style="color:#48b685">unix:/var/run/votre_domaine.sock</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">(…)</span>
</span></span><span style="display:flex;"><span><span style="color:#ef6155">}</span>
</span></span></code></pre></div><h3 id="php-fpm">PHP(-FPM)</h3>
<ul>
<li>
<p><code>/etc/php5/fpm/pool.d/*www*.conf</code>,</p>
</li>
<li>
<p>ou <code>/etc/php5/fpm/pool.d/*votre_domaine*.conf</code></p>
</li>
<li>
<p>vérifier la correspondance avec votre socket PHP :</p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">listen</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">/var/run/votre_domaine.sock</span>
</span></span></code></pre></div><ul>
<li>Il peut être utile de vérifier les déclarations suivantes, aussi :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">listen.owner</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">www-data</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen.group</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">www-data</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">listen.mode</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">0660</span>
</span></span></code></pre></div><p>Les déclarations <code>listen.owner</code> et <code>listen.group</code> sont impérativement liées
à l&rsquo;utilisateur et au groupe du service nginx, généralement <code>www-data</code>.<br>
À changer, selon votre configuration…</p>
<hr>
<p>Puis, redémarrez vos serveurs nginx, et php(x?)-fpm… les deux !</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre cette erreur - Error 502: Bad Gateway - de passerelle sous nginx]]></summary>
        <published>2017-07-23T22:39:58+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:023ec31d-d2ef-6753-1a52-a078a745f6f1</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-guide-bonnes-pratiques/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : Guide bonnes pratiques (RSA)</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <category term="Guide" scheme="http://doc.huc.fr.eu.org/fr/tags/guide/" />
        <category term="RSA" scheme="http://doc.huc.fr.eu.org/fr/tags/rsa/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Suite à mes précédentes réflexions à-propos du

<a class="inside" href="/fr/sec/gpg/gpg-usage-securise/" title="Lien interne vers l&#39;article : 'GPG : Du bon usage sécurisé'">Bon usage sécurisé de GPG</a>
,
finalement je me décide pour un article de ce genre : <strong>Guide des bonnes pratiques
pour la création de clés GPG</strong>.</p>
<p>De fait, il ne suffit pas de se dire, &ldquo;je vais créer ma clé à coup de
<code>--gen-key</code>, et puis zou…&rdquo;, ou d&rsquo;utiliser une interface graphique
pour le faire, telle qu&rsquo;Enigmail ou GPA, c&rsquo;est un processus un peu
plus long, d&rsquo;autant si l&rsquo;on veut le faire correctement !</p>
<p>Ce guide s&rsquo;inspire très fortement de celui d&rsquo;<a href="https://alexcabal.com/creating-the-perfect-gpg-keypair/" rel="external">Alex Cabal</a>…</p>
<hr>
<h2 id="création-parfaite-de-clés-gpg">Création parfaite de clés GPG</h2>
<h3 id="informations-importantes">Informations importantes</h3>
<ul>
<li><strong>Ne pas utiliser le paramétrage par défaut de GPG, à savoir : 2048 - et,
encore moins, inférieur !</strong></li>
<li><strong>La seule taille forte de clé, valide, à ce jour est : 4096 !</strong></li>
<li><strong>Le seul chiffrement à utiliser est : RSA !</strong></li>
</ul>
<h3 id="création">Création</h3>
<h4 id="création--clients-graphiques">Création : Clients Graphiques</h4>
<p>⇒ Pour <strong>Enigmail</strong>, il faut ouvrir la fenêtre de gestion de clés,
puis cliquer sur le menu &lsquo;<strong>Générer &gt; Nouvelle clé</strong>&rsquo;…</p>
<p>Il ne reste plus qu&rsquo;à choisir le courriel concerné, de créer une
passphrase, et de la répéter ; dans l&rsquo;onglet &lsquo;Expiration&rsquo;, veillez à
la durée : <span class="red">pas plus de 2 ans</span>
 !</p>
<p>Puis dans l&rsquo;onglet &lsquo;Avancé&rsquo;, vérifier la taille de la clé : 4096, le type de la
clé &lsquo;RSA&rsquo;…
vous n&rsquo;avez plus qu&rsquo;à cliquer sur le bouton [ Générer la clef ], et à
laisser faire le temps de la génération…</p>
<p>⇒ Avec <strong>GPA</strong>, c&rsquo;est sensiblement pareil, à la différence que c&rsquo;est
le menu <strong>&lsquo;Clefs&rsquo; &gt; &lsquo;Nouvelle clef&rsquo;</strong> qui permet de le
faire…</p>
<p>Choisissez l&rsquo;algorithme de chiffrement : RSA - <em>(RSA
(sign only) nous servira plus tard…)</em> -, la taille de clé - <em>il
est très probable qu&rsquo;il ne soit pas possible de chiffrer avec une clé
plus forte que 3072</em> - puis remplissez les champs &lsquo;Nom&rsquo;, et
&lsquo;Courriel&rsquo; seulement, et finissez par cliquez dans la case à cocher
&lsquo;Expires&rsquo;, pour choisir une date de 2 ans, maximum.</p>
<h4 id="création--mode-console">Création : Mode Console</h4>
<p>Il y a deux options pour créer une clé, l&rsquo;une permettant de faire plus
finement en demandant plus de choses que l&rsquo;autre, à savoir :</p>
<ul>
<li>l&rsquo;option <code>--gen-key</code>, version abrégée de l&rsquo;option <code>--generate-key</code>,</li>
<li>l&rsquo;option <code>--full-gen-key</code>, version abrégée de l&rsquo;option <code>--full-generate-key</code>.</li>
</ul>
<hr>
<p>Utilisons l&rsquo;option <code>--gen-key</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --gen-key
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 1.4.11; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2010</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and  redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Please <span style="color:#815ba4">select</span> what kind of key you want:
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span> RSA and RSA <span style="color:#5bc4bf">(</span>default<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span> DSA and Elgamal
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>sign only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>sign only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Your selection? **1**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>RSA keys may be between <span style="color:#f99b15">1024</span> and <span style="color:#f99b15">4096</span> bits long.
</span></span><span style="display:flex;"><span>What keysize <span style="color:#815ba4">do</span> you want? <span style="color:#5bc4bf">(</span>2048<span style="color:#5bc4bf">)</span> **4096**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Requested keysize is <span style="color:#f99b15">4096</span> bits
</span></span><span style="display:flex;"><span>Please specify how long the key should be valid.
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">0</span> <span style="color:#5bc4bf">=</span> key does not expire
</span></span><span style="display:flex;"><span>    &lt;n&gt;  <span style="color:#5bc4bf">=</span> key expires in n days
</span></span><span style="display:flex;"><span>    &lt;n&gt;w <span style="color:#5bc4bf">=</span> key expires in n weeks
</span></span><span style="display:flex;"><span>    &lt;n&gt;m <span style="color:#5bc4bf">=</span> key expires in n months
</span></span><span style="display:flex;"><span>    &lt;n&gt;y <span style="color:#5bc4bf">=</span> key expires in n years
</span></span><span style="display:flex;"><span>Key is valid <span style="color:#815ba4">for</span>? <span style="color:#5bc4bf">(</span>0<span style="color:#5bc4bf">)</span> **2y**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Is this correct? <span style="color:#5bc4bf">(</span>y/N<span style="color:#5bc4bf">)</span> **y**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>You need a user ID to identify your key; the software constructs the user ID
</span></span><span style="display:flex;"><span>from the Real Name, Comment and E-mail Address in this form:
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;Heinrich Heine (Der Dichter) &lt;heinrichh@duesseldorf.de&gt;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Real name: **Nom Prenom**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>E-mail address: **email@domain.tld**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Comment:
</span></span><span style="display:flex;"><span>You selected this USER-ID:
</span></span><span style="display:flex;"><span>    <span style="color:#48b685">&#34;Nom Prenom &lt;email@domain.tld&gt;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Change <span style="color:#5bc4bf">(</span>N<span style="color:#5bc4bf">)</span>ame, <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span>omment, <span style="color:#5bc4bf">(</span>E<span style="color:#5bc4bf">)</span>-mail or <span style="color:#5bc4bf">(</span>O<span style="color:#5bc4bf">)</span>kay/<span style="color:#5bc4bf">(</span>Q<span style="color:#5bc4bf">)</span>uit? **O**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>You need a Passphrase to protect your secret key.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>**demande votre passphrase**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg: key ******** marked as ultimately trusted
</span></span><span style="display:flex;"><span>public and secret key created and signed.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg: checking the trustdb
</span></span><span style="display:flex;"><span>gpg: <span style="color:#f99b15">3</span> marginal<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> needed, <span style="color:#f99b15">1</span> complete<span style="color:#5bc4bf">(</span>s<span style="color:#5bc4bf">)</span> needed, PGP trust model
</span></span><span style="display:flex;"><span>gpg: depth: <span style="color:#f99b15">0</span>  valid:   <span style="color:#f99b15">1</span>  signed:   <span style="color:#f99b15">0</span>  trust: 0-, 0q, 0n, 0m, 0f, 1u
</span></span><span style="display:flex;"><span>pub   4096R/******* 2013-03-13
</span></span><span style="display:flex;"><span>      Key <span style="color:#ef6155">fingerprint</span> <span style="color:#5bc4bf">=</span> **** **** **** **** ****  **** **** **** **** ****
</span></span><span style="display:flex;"><span>uid                  Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>sub   4096R/******** 2013-03-13
</span></span></code></pre></div><h3 id="ajout-dune-photo">Ajout d&rsquo;une photo</h3>
<p>Veillez à utiliser une photo qui soit de taille légère !</p>
<h4 id="addphoto--clients-graphiques">addphoto : Clients Graphiques</h4>
<p>⇒ <strong>Enigmail</strong> : il faut ouvrir la fenêtre de gestion de clés,
menu &ldquo;Édition&rdquo; &gt; &ldquo;Ajouter une photo&rdquo; après avoir sélectionné la clé.</p>
<ul>
<li><em>2ème possibilité</em> : clic droit sur la clé, menu contextuel &lsquo;Ajouter
une photo&quot;… et choisissez le fichier en question.</li>
<li><em>3ème possibilité</em> : clic droit sur la clé, menu contextuel &ldquo;Propriété de la clé&rdquo;,
puis dans la fenêtre de propriété, cliquez sur le bouton [ Sélectionnez une action … ]
et choisissez &lsquo;Ajouter une photo&rsquo;.</li>
</ul>
<p>⇒ <strong>GPA</strong> semble ne pas en être capable !</p>
<h4 id="addphoto--mode-console">addphoto : Mode Console</h4>
<p>C&rsquo;est l&rsquo;option <code>--edit-key</code> qui sera utilisée puis l&rsquo;option <code>addphoto</code>, telles que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --edit-key email@domain.tld
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 1.4.11; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2010</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Secret key is available.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; addphoto
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Pick an image to use <span style="color:#815ba4">for</span> your photo ID.  The image must be a JPEG file.
</span></span><span style="display:flex;"><span>Remember that the image is stored within your public key.  If you use a
</span></span><span style="display:flex;"><span>very large picture, your key will become very large as well!
</span></span><span style="display:flex;"><span>Keeping the image close to 240x288 is a good size to use.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Enter JPEG filename <span style="color:#815ba4">for</span> photo ID: /repertoire_vers_photo/photo.jpg
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Is this photo correct <span style="color:#5bc4bf">(</span>y/N/q<span style="color:#5bc4bf">)</span>? y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>You need a passphrase to unlock the secret key <span style="color:#815ba4">for</span>
</span></span><span style="display:flex;"><span>user: <span style="color:#48b685">&#34;Nom Prenom &lt;email@domain.tld&gt;&#34;</span>
</span></span><span style="display:flex;"><span>4096-bit RSA key, ID ********, created 2013-03-13
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>**demande votre passphrase**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> unknown<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span>  <span style="color:#5bc4bf">[</span>jpeg image of size 5324<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; save
</span></span></code></pre></div><h3 id="préférences-hash">Préférences Hash</h3>
<p>Paramétrer les hash préférés sont de bon aloi !</p>
<h4 id="setpref--clients-graphiques">setpref : Clients Graphiques</h4>
<p>⇒ <strong>Enigmail</strong> semble ne pas en être capable !</p>
<p>⇒ <strong>GPA</strong> semble ne pas en être capable !</p>
<h4 id="setpref--mode-console">setpref : Mode Console</h4>
<p>C&rsquo;est encore l&rsquo;option <code>--edit-key</code> qui sera utilisée mais avec
l&rsquo;option <code>setpref</code>, telles que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --edit-key email@domain.tld
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 1.4.11; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2010</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Secret key is available.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span>  <span style="color:#5bc4bf">[</span>jpeg image of size 5324<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Set preference list to:
</span></span><span style="display:flex;"><span>     Cypher: AES256, AES192, AES, CAST5, 3DES
</span></span><span style="display:flex;"><span>     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
</span></span><span style="display:flex;"><span>     Compression: ZLIB, BZIP2, ZIP, Uncompressed
</span></span><span style="display:flex;"><span>     Features: MDC, Keyserver no-modify
</span></span><span style="display:flex;"><span>Really update the preferences? <span style="color:#5bc4bf">(</span>y/N<span style="color:#5bc4bf">)</span> y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>You need a passphrase to unlock the secret key <span style="color:#815ba4">for</span>
</span></span><span style="display:flex;"><span>user: <span style="color:#48b685">&#34;Nom Prenom &lt;email@domain.tld&gt;&#34;</span>
</span></span><span style="display:flex;"><span>4096-bit RSA key, ID ********, created 2013-03-13
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>**demande votre passphrase**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> unknown<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span>  <span style="color:#5bc4bf">[</span>jpeg image of size 5324<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; save
</span></span></code></pre></div><h3 id="une-nouvelle-sous-clé-de-signature">Une nouvelle sous-clé de signature</h3>
<p>Cette étape est vraiment importante ; elle sert à créer une sous-clé qui
ne servira qu&rsquo;à signer de nouveaux messages et autres documents…</p>
<p>Si vous vous passez des deux étapes précédentes, ne vous passez pas de
celle-ci ; vous comprendrez plus bas le pourquoi !</p>
<p><strong>Les recommandations de création de cette sous-clé sont ABSOLUMENT les mêmes
que pour la création de la clé principale !</strong></p>
<p><em>Quoi ?</em> <br>
vous avez déjà oublié : RSA + 4096 bits - avec la différence qu&rsquo;on utilisera le
choix &lsquo;RSA (sign only)&rsquo;, et pas besoin de paramétrer une période de validité…</p>
<h4 id="addkey--clients-graphiques">addkey : Clients Graphiques</h4>
<p>⇒ <strong>Enigmail</strong> semble ne pas en être capable !</p>
<p>⇒ <strong>GPA</strong> semble ne pas être capable de générer de clés dont la taille soit de
4096 bits, sinon, c&rsquo;est menu &ldquo;Clefs&rdquo; &gt; &ldquo;Nouvelle clé&rdquo; ; choisir l&rsquo;algorithme &lsquo;RSA (sign only)&rsquo;,
remplir les champs &lsquo;Nom&rsquo;, &lsquo;Courriel&rsquo; - sur ce dernier, remplir l&rsquo;adresse mail
correspondante, et ne pas cochez la case &lsquo;Expirer&rsquo; puis validez !</p>
<h4 id="addkey-mode-console">addkey: Mode Console</h4>
<p>C&rsquo;est toujours l&rsquo;option <code>--edit-key</code> qui sera utilisée mais cette fois-ci avec
l&rsquo;option <code>addkey</code>, telles que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --edit-key email@domain.tld
</span></span><span style="display:flex;"><span>gpg <span style="color:#5bc4bf">(</span>GnuPG<span style="color:#5bc4bf">)</span> 1.4.11; Copyright <span style="color:#5bc4bf">(</span>C<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">2010</span> Free Software Foundation, Inc.
</span></span><span style="display:flex;"><span>This is free software: you are free to change and redistribute it.
</span></span><span style="display:flex;"><span>There is NO WARRANTY, to the extent permitted by law.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Secret key is available.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span>  <span style="color:#5bc4bf">[</span>jpeg image of size 5324<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; addkey
</span></span><span style="display:flex;"><span>Key is protected.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>You need a passphrase to unlock the secret key <span style="color:#815ba4">for</span>
</span></span><span style="display:flex;"><span>user: <span style="color:#48b685">&#34;Nom Prenom &lt;email@domain.tld&gt;&#34;</span>
</span></span><span style="display:flex;"><span>4096-bit RSA key, ID ********, created 2013-03-13
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>**demande votre passphrase**
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Please <span style="color:#815ba4">select</span> what kind of key you want:
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>3<span style="color:#5bc4bf">)</span> DSA <span style="color:#5bc4bf">(</span>sign only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>4<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>sign only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>5<span style="color:#5bc4bf">)</span> Elgamal <span style="color:#5bc4bf">(</span>encrypt only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#5bc4bf">(</span>6<span style="color:#5bc4bf">)</span> RSA <span style="color:#5bc4bf">(</span>encrypt only<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Your selection? <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>RSA keys may be between <span style="color:#f99b15">1024</span> and <span style="color:#f99b15">4096</span> bits long.
</span></span><span style="display:flex;"><span>What keysize <span style="color:#815ba4">do</span> you want? <span style="color:#5bc4bf">(</span>2048<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">4096</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Requested keysize is <span style="color:#f99b15">4096</span> bits
</span></span><span style="display:flex;"><span>Please specify how long the key should be valid.
</span></span><span style="display:flex;"><span>    <span style="color:#ef6155">0</span> <span style="color:#5bc4bf">=</span> key does not expire
</span></span><span style="display:flex;"><span>    &lt;n&gt;  <span style="color:#5bc4bf">=</span> key expires in n days
</span></span><span style="display:flex;"><span>    &lt;n&gt;w <span style="color:#5bc4bf">=</span> key expires in n weeks
</span></span><span style="display:flex;"><span>    &lt;n&gt;m <span style="color:#5bc4bf">=</span> key expires in n months
</span></span><span style="display:flex;"><span>    &lt;n&gt;y <span style="color:#5bc4bf">=</span> key expires in n years
</span></span><span style="display:flex;"><span>Key is valid <span style="color:#815ba4">for</span>? <span style="color:#5bc4bf">(</span>0<span style="color:#5bc4bf">)</span> <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Key does not expire at all
</span></span><span style="display:flex;"><span>Is this correct? <span style="color:#5bc4bf">(</span>y/N<span style="color:#5bc4bf">)</span> y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Really create? <span style="color:#5bc4bf">(</span>y/N<span style="color:#5bc4bf">)</span> y
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
</span></span><span style="display:flex;"><span>                     trust: ultimate      validity: ultimate
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never       usage: E
</span></span><span style="display:flex;"><span>sub  4096R/********  created: 2013-03-13  expires: never
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>ultimate<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>1<span style="color:#5bc4bf">)</span>. Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span> unknown<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">(</span>2<span style="color:#5bc4bf">)</span>  <span style="color:#5bc4bf">[</span>jpeg image of size 5324<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gpg&gt; save
</span></span></code></pre></div><h3 id="création-du-certificat-de-révocation">Création du certificat de révocation</h3>
<p>La création du certificat de révocation est une étape à faire ABSOLUMENT !</p>
<p><strong>En effet, celui-ci vous sera nécessaire pour révoquer votre clé GPG, ou la
sous-clé de signature, si jamais vous avez perdu celle-ci, et/ou qu&rsquo;elle soit
volée, et/ou qu&rsquo;elle soit compromise !</strong></p>
<p><strong>Il vous importe de placer ce certificat de révocation dans un endroit sûr !</strong></p>
<h4 id="revoke--clients-graphiques">revoke : Clients graphiques</h4>
<p>⇒ <strong>Enigmail</strong> : Clic droit sur la clé, menu contextuel
&ldquo;Créer et enregistrer un certificat de révocation&rdquo;.</p>
<ul>
<li><em>2ème possibilité</em> : clic droit sur la clé, menu contextuel &ldquo;Propriétés de la clé&rdquo;,
puis dans la fenêtre &ldquo;Propriété&rdquo;, cliquez sur le bouton [ Sélectionnez l&rsquo;action …],
puis &ldquo;Créer et enregistrer un certificat de révocation&rdquo;.</li>
</ul>
<p>⇒ <strong>GPA</strong> semble ne pas en être capable !</p>
<h4 id="revoke--mode-console">revoke : mode console</h4>
<p>C&rsquo;est assez simple, pour une fois :</p>
<p><code>$ gpg --output email@domain.tld.rev.asc --gen-revoke email@domain.tld</code></p>
<h3 id="exportez-vos-clés">Exportez vos clés</h3>
<p>L&rsquo;export de vos clés fait partie du processus nécessaire. <br>
<strong>Bien entendu, il vous incombe de mettre en lieu sûr ces fichiers, IMPÉRATIVEMENT
la clé privée qui en résulte !</strong></p>
<h4 id="export--clients-graphiques">export : Clients graphiques</h4>
<p>⇒ <strong>Enigmail</strong> : clic droit sur la clé, menu contextuel &ldquo;Exporter les clés vers un fichier&rdquo;</p>
<p>⇒ <strong>GPA</strong> : Menu &lsquo;Clefs&rsquo; &gt; &lsquo;Exporter des clefs&rsquo;</p>
<p><em>2ème possibilité</em> : clic droit sur la clé en question, puis dans le menu contextuel,
choisir &lsquo;Exporter des clefs&rsquo;…</p>
<h4 id="export--mode-console-">export : mode console :</h4>
<pre tabindex="0"><code>$ gpg --export-secret-keys --armor email@domain.tld &gt; email@domain.tld.private_key.asc
$ gpg --export --armor email@domain.tld &gt; email@domain.tld.public_key.asc
</code></pre><h3 id="transformons-les-clés">Transformons les clés</h3>
<p>Transformez les clés que nous avons créées, dites clés primaires en clés
portables ou mode &ldquo;protégé&rdquo;, est un autre processus IMPORTANT !</p>
<p>Ce processus est un peu long, non-prévu dans le fonctionnement interne
de GPG, <em>peut faire peur - et donner des suées</em>,…</p>
<p>Il a pour propos d&rsquo;extraire les sous-clés, de les détruire du porte-clé, de les
importer correctement !</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : Une fois, en mode &ldquo;protégé&rdquo;, les clés ne sont plus éditables,
ni modifiables… <br>
vous aurez le droit au final  à l&rsquo;erreur &ldquo;<a class="inside" href="/fr/sec/gpg/gpg-erreurs/#gpg-des-parties-de-la-clef-secr%c3%a8te-ne-sont-pas-disponibles" title="Lien interne vers l&#39;article : 'GPG : les messages d&#39;erreurs'">gpg: des parties de la clef secrète ne sont pas disponibles</a>
&ldquo;, et rien de
ce que vous aurez pu faire, demandé, exécuté dans la  modification de la clé ne
sera acté, validé !</p>
<p>De même, vous ne pourrez pas signer une autre clé avec !</p>
</div>

<h4 id="transformation--clients-graphiques">transformation : Clients Graphiques</h4>
<p>Ne cherchez pas ; ce processus n&rsquo;est pas du tout géré !</p>
<h4 id="transformation--mode-console">transformation : Mode Console</h4>
<p>Tout d&rsquo;abord un aperçu de la clé, pour comparaison :</p>
<p><em>celui-ci n&rsquo;est absolument pas nécessaire - juste pour aider à remarquer la légère
différence, avant ce processus et après !</em></p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --list-secret-keys
</span></span><span style="display:flex;"><span>/home/<span style="color:#ef6155">$USER</span>/.gnupg/secring.gpg
</span></span><span style="display:flex;"><span>-----------------------------
</span></span><span style="display:flex;"><span>sec  4096R/******** 2013-03-13
</span></span><span style="display:flex;"><span>uid                  Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>ssb   4096R/******** 2013-03-13
</span></span><span style="display:flex;"><span>ssb   4096R/******** 2013-03-13
</span></span></code></pre></div><p>Maintenant, le processus de transformation - que vous devez exécutez :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --export-secret-subkeys email@domain.tld &gt; ~/.gnupg/email@domain.tld.subkeys
</span></span><span style="display:flex;"><span>:$ gpg --delete-secret-keys email@domain.tld
</span></span><span style="display:flex;"><span>:$ gpg --import ~/.gnupg/email@domain.tld.subkeys
</span></span><span style="display:flex;"><span>:$ shred --remove ~/.gnupg/email@domain.tld.subkeys
</span></span></code></pre></div><p>Comparons :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:$ gpg --list-secret-keys
</span></span><span style="display:flex;"><span>/home/<span style="color:#ef6155">$USER</span>/.gnupg/secring.gpg
</span></span><span style="display:flex;"><span>-----------------------------
</span></span><span style="display:flex;"><span>sec#  4096R/******** 2013-03-13
</span></span><span style="display:flex;"><span>uid                  Nom Prenom &lt;email@domain.tld&gt;
</span></span><span style="display:flex;"><span>ssb   4096R/******** 2013-03-13
</span></span><span style="display:flex;"><span>ssb   4096R/******** 2013-03-13
</span></span></code></pre></div><p>En fait la différence visible/visuelle est très légère : sur la ligne
commençant par le mot <code>sec</code>, celui-ci est suivi du symbole <code>#</code>…</p>
<p>La présence du symbole dièze signifie que la sous-clé de
signature ne fait pas partie du trousseau de clé !</p>
<p><strong><span class="red">Si le symbole dièze n'est pas présent, c'est qu'il y a eu un
problème dans la phase de ce processus… refaites-le !</span>
</strong></p>
<hr>
<p>Voilà, vous avez suivi toutes ces étapes - c&rsquo;est très bien. Elles vous
garantissent d&rsquo;avoir fait correctement les choses ;-)</p>
<h2 id="partagez-votre-clé-publique-">Partagez votre clé publique !</h2>
<p>Allez n&rsquo;hésitez pas à partagez, publiez votre clé publique - informez
de l&rsquo;empreinte relative à votre clé publique - privilégiez le contact
réel, physique lors de cet échange…</p>
<h3 id="en-mode-graphique-">En mode graphique :</h3>
<p>⇒ <strong>Enigmail</strong> : Menu &ldquo;Serveur de clefs&rdquo; &gt; &ldquo;Envoyer les clés publiques&rdquo;.</p>
<p><em>2ème possibilité</em> : clic droit sur la clé, menu contextuel &ldquo;Envoyer
les clés publiques vers un serveur de clefs&rdquo;</p>
<p>⇒ <strong>GPA</strong> : Menu &lsquo;Serveur&rsquo; &gt; &lsquo;Envoyer des clefs&rsquo;.</p>
<p><em>2ème possibilité</em> : clic droit sur la clé, puis dans le menu contextuel,
choisissez &lsquo;Envoyer des clefs&rsquo; ; confirmez votre choix, si cela vous est demandé
en cliquant sur le bouton [Oui].</p>
<h3 id="en-mode-console-">En mode console :</h3>
<p>Utilisez donc l&rsquo;option <code>--send-keys &quot;fingerprint</code>, tel que : <br>
<code>$ gpg --send-keys &quot;fingerprint&quot;</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p>Si vous avez paramétré correctement votre fichier personnel <code>~/.gnupg/gpg.conf</code>
comme je vous l&rsquo;ai démontré dans mon
<a class="inside" href="/fr/sec/gpg/gpg-usage-securise/" title="Lien interne vers l&#39;article : 'GPG : Du bon usage sécurisé'">GPG : Du bon usage sécurisé</a></p>
<p>,
alors vous n&rsquo;aurez même pas besoin de spécifier le serveur, et en plus,
cela se fera de manière sécurisée !</p>
</div>

<h2 id="de-bonnes-lectures">De bonnes lectures</h2>
<p>Je renvoie très fortement vers les bonnes lectures en question :</p>
<ul>
<li>le <a href="https://www.gnupg.org/howtos/fr/GPGMiniHowto.html" rel="external">Mini-Guide Howto</a>- par GnuPG…</li>
<li>le <a href="https://emailselfdefense.fsf.org/fr/index.html" rel="external">Guide Autodéfense Courriel</a>- par la FSF…</li>
<li>le guide autodéfense numérique - tome 2 : <a href="https://guide.boum.org/tomes/2_en_ligne/3_outils/07_utiliser_openpgp/04_creer_et_maintenir_une_paire_de_cles/" rel="external">Comment créer et maintenir une clé GPG</a>-</li>
<li>ou, les <a href="https://help.riseup.net/fr/security/message-security/openpgp/best-practices" rel="external">bonnes pratiques pour l&rsquo;utilisation d&rsquo;OpenPGP</a>…</li>
</ul>
<hr>
<h2 id="du-bon-outil-gpg">Du bon outil GPG</h2>
<h3 id="mon-script-shell-posix">Mon script shell POSIX</h3>
<p>Vous retrouverez mon <a href="https://framagit.org/hucste/tools/blob/master/mng_gpg" rel="external">script de gestion de clé GPG</a>
sur mon espace git <br>
<em>Du moins, j&rsquo;espère bien qu&rsquo;il soit POSIX</em></p>
<ul>
<li>Pour afficher l&rsquo;aide : <code>./mng_gpg help</code></li>
<li>Pour génèrer une clé : <code>./mng_gpg create</code></li>
</ul>
<p>Pour information, cet outil a aussi besoin de l&rsquo;outil <code>shred</code>…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Guide des bonnes pratiques pour créer et utiliser correctement des clés GPG en utilisant l&#39;algorithme RSA.]]></summary>
        <published>2017-07-23T21:15:37+01:00</published>
        <updated>2017-07-28T12:18:37+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4149b0ec-4d2c-d4fd-ac23-faaaf128e585</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/nginx/perishablepress-blackhole/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PerishablePress : Blackhole pour les mauvais robots</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="nginx" scheme="http://doc.huc.fr.eu.org/fr/tags/nginx/" />
        <category term="PerishablePress" scheme="http://doc.huc.fr.eu.org/fr/tags/perishablepress/" />
        <category term="Blackhole" scheme="http://doc.huc.fr.eu.org/fr/tags/blackhole/" />
        <category term="block" scheme="http://doc.huc.fr.eu.org/fr/tags/block/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Jeff Starr de PersishablePress vient de publier son <a href="https://perishablepress.com/new-plugin-blackhole-bad-bots/" rel="external">plugin de sécurité pour WP</a>,
nommé <span lang="en"><a href="https://perishablepress.com/blackhole-bad-bots/" rel="external">Blackhole for BadBots</a></span>.</p>
<p>L&rsquo;idée de départ intéressante est, dû au fait que les robots scrutateurs
du web ne respectent pas tous la déclaration du fichier <code>robots.txt</code>…</p>
<p>C&rsquo;est d&rsquo;ailleurs pour cette raison qu&rsquo;ils sont appelés &ldquo;<span lang="en">BadBots</span>&rdquo;
ou &ldquo;mauvais robots&rdquo;.</p>
<p>Puisque ces mauvais robots ne respectent rien, on va les piéger, puis bloquer
leurs adresses IP !</p>
<h2 id="installation">Installation</h2>
<p>Commençons par télécharger la dernière mouture des scripts PHP :<br>
<a href="https://perishablepress.com/blackhole-bad-bots/#blackhole-download" rel="external">https://perishablepress.com/blackhole-bad-bots/#blackhole-download</a></p>
<p>Une fois l&rsquo;archive décompressée, ouvrez le script <code>index.php</code>, et modifiez
correctement les valeurs des variables <code>$from</code>, <code>$recip</code>…<br>
enregistrez la modification.</p>
<p>Pensez à modifiez l&rsquo;url de contact, en lignes 206 et 229 ; et, idem pour
le script <code>blackhole.php</code> en ligne 56.</p>
<p>Dans votre site, créez un répertoire <code>blackhole</code>, dans lequel vous déposerez
les fichiers blackhole, précédemment téléchargés - <br>
<em>bien sûr, pas besoin du fichier <code>.htaccess</code></em></p>
<p>Mettez des droits 0600 sur le fichier <code>blackhole.dat</code>, si votre serveur
permet cette gestion fine…</p>
<h2 id="configuration">Configuration</h2>
<p>Ensuite, modifiez vos scripts PHP de cette manière - <em>oui, là, c&rsquo;est un peu la contrainte !</em> :</p>
<ul>
<li>Dans votre code source PHP, rajoutez cette déclaration suivante - <em>si possible,
avant tout code html… voire tout autre code PHP</em> :<br>
<code>include(realpath(getenv('DOCUMENT_ROOT')) .'/blackhole/blackhole.php');</code></li>
<li>Toujours dans le code source PHP, rajoutez la suivante, où vous voulez,
mais le plus probablement dans ce qu&rsquo;on appelle le &lsquo;footer&rsquo; :<br>
<code>&lt;a rel=&quot;nofollow&quot; style=&quot;display:none;&quot; href=&quot;http://votre-ndd.tld/blackhole/&quot;&gt;NE PAS Suivre ce lien où vous serez bannis - interdits d'accès - à ce site !&lt;/a&gt;</code></li>
<li>Puis, terminez par rajouter cette déclaration dans votre fichier <code>robots.txt</code> :<br>
<code>Disallow: /blackhole/</code></li>
</ul>
<p>Maintenant, modifions le fichier de configuration de votre serveur nginx
pour ajouter cette déclaration <code>location</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span>    <span style="color:#815ba4">location</span> <span style="color:#48b685">/blackhole/blackhole.dat</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">satisfy</span> <span style="color:#48b685">any</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#5bc4bf">deny</span> <span style="color:#48b685">all</span>;
</span></span><span style="display:flex;"><span>    }
</span></span></code></pre></div><p>Puis, pensez à tester votre configuration nginx, et redémarrez votre serveur !</p>
<p>Vous obtiendrez ainsi une belle erreur 404, si le fichier est appelé…</p>
<hr>
<p>À partir de maintenant, quand un mauvais robot, ou quelqu&rsquo;un cherchera à
pointer sur le répertoire <code>blackhole</code>, et/ou un de ses fichiers, il sera
blacklisté, puis quand il reviendra, il ne lui sera pas permis d&rsquo;avoir
accès au site web…</p>
<p>Le script vous enverra un mail ; si vous ne voulez pas en recevoir, éditez
le script <code>index.php</code>, et mettez en commentaire PHP la ligne 226, commençant ainsi :<br>
<code>//mail($recip, $subject, $message, 'From: '. $from);</code></p>
<p>Il existe d&rsquo;autres options modifiables ; là, je vous renvoie au site <a href="https://perishablepress.com/blackhole-bad-bots/" rel="external">PerishablePress</a> !</p>
<hr>
<p><strong>Version modifiée</strong></p>
<p>Retrouvez la <a href="https://framagit.org/hucste/tools/tree/master/blackhole" rel="external">version modifiée sur mon espace git</a>, ainsi que l&rsquo;<a href="https://framagit.org/hucste/tools/raw/master/blackhole/blackhole.modified.zip" rel="external">archive ZIP correspondante</a> !</p>
<p>L&rsquo;auteur est informé ; j&rsquo;espère qu&rsquo;il intégrera mes modifications ;-)</p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[PerishablePress : ajouter des règles de sécurité à nginx pour bloquer les mauvais robots]]></summary>
        <published>2017-07-23T21:42:02+02:00</published>
        <updated>2017-07-29T22:17:58+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:d6145f8c-0c34-d842-ae6a-ea80faacbec5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-renew/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : renouvellement de ma clé</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <category term="Renouvellement" scheme="http://doc.huc.fr.eu.org/fr/tags/renouvellement/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Enfin, cela fait presque deux ans, à une ou deux semaines près, que j&rsquo;ai créé
ma précédente clé GPG … il va falloir la renouveler, n&rsquo;est-ce pas !</p>
<p>Il y a deux manières de faire cela :</p>
<ul>
<li><strong>si et seulement si</strong> votre clé est toujours conforme aux recommandations
actuelles de choix d’algorithmes, de taille de celle-ci - à savoir RSA 4096 -
alors il est possible d&rsquo;envisager de
<a href="/fr/sec/gpg/gpg-renew/#modifier-la-date-d-expiration">modifier la date d&rsquo;expiration</a></li>
<li>si vous préférez recréer une clé, pour quelle que raison que ce soit, alors
il suffit de <a href="/fr/sec/gpg/gpg-renew/#création_d_une_nouvelle_clé">créer une nouvelle clé</a>,
relative toujours à la même adresse mail…</li>
</ul>
<h2 id="modifier-la-date-dexpiration">Modifier la date d&rsquo;expiration</h2>
<p>Repousser la date d&rsquo;expiration est très simple, il faut éditer la clé en utilisant
son empreinte, bien-sûr : <br>
<em>Et oui, pour rappel, on édite sa clé à partir de son empreinte gpg, et non pas
sa clé gpg ou l&rsquo;email correspondant !</em></p>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">:$ gpg --edit-key &#34;CBC8 A5AB C6A6 2F2C C414  E869 DA43 05B9 BE07 311F&#34;
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

La clef secrète est disponible.

sec  ed25519/0xDA4305B9BE07311F
     créé : 2020-01-30  expirée : 2022-01-29  utilisation : SC
     confiance : ultime        validité : expirée
ssb  cv25519/0x9BA14C4E01678087
     créé : 2020-01-30  expirée : 2022-01-29  utilisation : E
ssb  ed25519/0xBA82BCDF5858BA77
     créé : 2020-01-30  expirée : jamais      utilisation : S
[ expirée ] (1). Stéphane HUC &lt;consult@huc.fr.eu.org&gt;
[ expirée ] (2)  Stéphane HUC &lt;consult@stephane-huc.net&gt;

gpg&gt;
</code></pre><p>Utilisons l&rsquo;option <code>expire</code>, tel que :</p>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">gpg&gt; expire
Modification de la date d&#39;expiration de la clef principale.
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n&#39;expire pas
      &lt;n&gt;  = la clef expire dans n jours
      &lt;n&gt;w = la clef expire dans n semaines
      &lt;n&gt;m = la clef expire dans n mois
      &lt;n&gt;y = la clef expire dans n ans
Pendant combien de temps la clef est-elle valable ? (0) 1y
La clef expire le jeu. 23 mars 2023 09:56:03 CET
Est-ce correct ? (o/N) o

sec  ed25519/0xDA4305B9BE07311F
     créé : 2020-01-30  expire : 2023-03-23  utilisation : SC
     confiance : ultime        validité : ultime
ssb  cv25519/0x9BA14C4E01678087
     créé : 2020-01-30  expirée : 2022-01-29  utilisation : E
ssb  ed25519/0xBA82BCDF5858BA77
     créé : 2020-01-30  expire : jamais      utilisation : S
[  ultime ] (1). Stéphane HUC &lt;consult@huc.fr.eu.org&gt;
[  ultime ] (2)  Stéphane HUC &lt;consult@stephane-huc.net&gt;

gpg: Attention : votre sous-clef de chiffrement expire bientôt.
gpg: Vous pourriez modifier aussi sa date d’expiration.
gpg&gt;
</code></pre><p>Ainsi que l&rsquo;affiche l&rsquo;avertissement, il est nécessaire de modifier aussi
les dates d&rsquo;expirations de vos sous-clés, si vous en avez, en utilisant
l&rsquo;option <code>key</code>, tel que :</p>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">gpg&gt; key 0xBA82BCDF5858BA77

sec  ed25519/0xDA4305B9BE07311F
     créé : 2020-01-30  expire : 2023-03-23  utilisation : SC
     confiance : ultime        validité : ultime
ssb* cv25519/0x9BA14C4E01678087
     créé : 2020-01-30  expire : 2023-03-23  utilisation : E
ssb* ed25519/0xBA82BCDF5858BA77
     créé : 2020-01-30  expire : jamais      utilisation : S
[  ultime ] (1). Stéphane HUC &lt;consult@huc.fr.eu.org&gt;
[  ultime ] (2)  Stéphane HUC &lt;consult@stephane-huc.net&gt;

gpg&gt; expire
Are you sure you want to change the expiration time for multiple subkeys? (y/N) y
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n&#39;expire pas
      &lt;n&gt;  = la clef expire dans n jours
      &lt;n&gt;w = la clef expire dans n semaines
      &lt;n&gt;m = la clef expire dans n mois
      &lt;n&gt;y = la clef expire dans n ans
Pendant combien de temps la clef est-elle valable ? (0) 1y
La clef expire le jeu. 23 mars 2023 09:57:39 CET
Est-ce correct ? (o/N) o

sec  ed25519/0xDA4305B9BE07311F
     créé : 2020-01-30  expire : 2023-03-23  utilisation : SC
     confiance : ultime        validité : ultime
ssb* cv25519/0x9BA14C4E01678087
     créé : 2020-01-30  expire : 2023-03-23  utilisation : E
ssb* ed25519/0xBA82BCDF5858BA77
     créé : 2020-01-30  expire : 2023-03-23  utilisation : S
[  ultime ] (1). Stéphane HUC &lt;consult@huc.fr.eu.org&gt;
[  ultime ] (2)  Stéphane HUC &lt;consult@stephane-huc.net&gt;

gpg&gt;
</code></pre><p>Faire de même pour tout autre sous-clé…</p>
<p>N&rsquo;oubliez surtout pas d&rsquo;enregister vos modifications grâce à l&rsquo;option <code>save</code> :</p>
<pre tabindex="0"><code class="language-gpg" data-lang="gpg">gpg&gt; save
$
</code></pre><p>ce qui vous renverra sous votre invite shell.</p>
<h3 id="envoi-au-serveur-de-clé-gpg">Envoi au serveur de clé GPG</h3>
<h4 id="cas-normal-de-serveur-de-clé">cas normal de serveur de clé</h4>
<p>Pour finir, n&rsquo;oubliez pas de l&rsquo;envoyer au serveur : <br>
<code>$ gpg --send-key &quot;fingerprint&quot;</code>.</p>
<h4 id="serveur-keysopenpgporg">serveur keys.openpgp.org</h4>
<p>Sauf si votre serveur est <strong>keys.OpenPGP.org</strong>, faites alors :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ gpg --export <span style="color:#48b685">&#34;fingerprint&#34;</span> | curl -T - https://keys.openpgp.org
</span></span></code></pre></div><p>Normallement, vous aurez un message de réussite, tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>Key successfully uploaded. Proceed with verification here:
</span></span><span style="display:flex;"><span>https://keys.openpgp.org/upload/***
</span></span></code></pre></div><p>Cliquez sur le lien ou copiez-le dans votre navigateur, et confirmez l&rsquo;ajout
comme il vous sera demandé par le biais du site.</p>
<h3 id="pour-finir">Pour finir</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pensez à créer vos fichiers d&rsquo;export de clé privée, publique, voire de créer
votre fichier de révocation ! <br>
Et, bien-sûr à les sécuriser…</div>

<h2 id="création-dune-nouvelle-clé">Création d&rsquo;une nouvelle clé</h2>
<p>Comme j&rsquo;aime bien faire les choses, qu&rsquo;il s&rsquo;est passé près de deux ans, entre
temps - <em>voire plus</em> -, je me penche à nouveau sur la lecture de cet article :
&ldquo;<strong><a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">Guide bonnes pratiques de création GPG</a>
</strong>&rdquo;.</p>
<p>Une fois que vous avez créé la nouvelle, suivez ces étapes très simples :</p>
<ul>
<li>Signez publiquement la nouvelle clé, avec votre ancienne clé - cela montrera
que vous lui faites confiance… <br>
<code>$ gpg --default-key &quot;fingerprint clé qui sert à signer&quot; --sign-key &quot;fingerprint clé à signer&quot;</code></li>
<li>Exportez votre nouvelle clé, en la publiant sur un des serveurs SKS… <br>
<code>$ gpg --send-key &quot;fingerprint&quot;</code></li>
<li>Arrivé à expiration, il va falloir révoquer votre ancienne clé, et publiez le
fait que l&rsquo;ancienne clé soit révoquée - et là, je vous renvoie au mon mémo
&ldquo;<strong>
<a class="inside" href="/fr/sec/gpg/gpg-revoque/" title="Lien interne vers l&#39;article : 'GPG : révoquer une clé'">GPG Révocation de clé</a>
</strong>&rdquo;.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Tutoriel pour comprendre comment renouveller une clé GPG]]></summary>
        <published>2017-07-23T19:43:38+01:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:317ee70f-5c3c-173d-30ee-06db2d09c1c9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/gpg/gpg-revoque/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: GPG : révoquer une clé</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="GPG" scheme="http://doc.huc.fr.eu.org/fr/tags/gpg/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Pour une raison ou l&rsquo;autre, il vous est impératif de révoquer votre clé… <br>
alors révoquons !</p>
<p>Les raisons :</p>
<ul>
<li>Une clé qui arrive à expiration…</li>
<li>Une clé qui est perdue, volée…</li>
<li>Une clé, malheureusement, compromise…</li>
</ul>
<h2 id="révocation">Révocation</h2>
<p>L&rsquo;acte de révocation est un acte simple, à partir du moment où vous avez bel et
bien votre fichier de révocation relatif à la clé en question !</p>
<p>Dans le cas où votre clé arrive à expiration, il est toujours temps de (re?)générer
un certificat de révocation… <br>
<em>je vous renvoie à la lecture de mon article :
&ldquo;<a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/#cr%c3%a9ation-du-certificat-de-r%c3%a9vocation" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">Guide bonnes pratiques de création GPG</a>
&rdquo;
au chapitre &ldquo;Création du certificat de révocation&rdquo; !</em> ;-)</p>
<p>Pour importer le certificat de révocation, on s&rsquo;y prend ainsi :</p>
<p><code>$ gpg --import ~/.gnupg/email@domain.tld.rev.asc</code></p>
<p>Maintenant il faut l&rsquo;éditer, puis utiliser l&rsquo;option <code>revkey</code> :</p>
<p>Si vous révoquez votre clé parce que :</p>
<ul>
<li>elle a été compromise, volée, perdue ; indiquez le choix
&lsquo;<span lang="en"><code>Key has been compromised</code></span>&rsquo;</li>
<li>elle est arrivée à expiration ; indiquez le choix
&lsquo;<span lang="en"><code>Key is no longer used</code></span>&rsquo;.</li>
<li>elle est remplacée pour utiliser de meilleurs algorithmes, pour la rendre
plus &ldquo;forte&rdquo;, etc… : <br>
indiquez le choix &lsquo;<span lang="en"><code>Key is superseded</code></span>&rsquo;.</li>
<li>si vous ne voulez pas donner de raisons, indiquez le choix
&lsquo;<span lang="en"><code>No reason specified</code></span>&rsquo;.</li>
</ul>
<pre tabindex="0"><code>:$ gpg --edit-key email@domain.tld
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
sub  4096R/********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; revkey


Do you really want to revoke the selected subkeys? (y/N) **y**

Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
Your decision? **votre choix**

Enter an optional description; end it with an empty line:
&gt;
Reason for revocation: Key is no longer used
(No description given)
Is this okay? (y/N) y


You need a passphrase to unlock the secret key for
user: &#34;Nom Prenom &amp;lt;email@domain.tld&gt;&#34;
4096-bit RSA key, ID ********, created 2013-03-13

**demande votre passhphrase**

pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
This key was revoked on 2013-03-13 by RSA key ******** Nom Prenom
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
This key was revoked on 2013-03-13 by RSA key ******** Nom Prenom
sub  4096R/*********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; save
</code></pre><h3 id="cas-particulier-des-sous-clés">Cas particulier des sous-clés</h3>
<p>Dans mon mémoriel &ldquo;<a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/#transformons-les-cl%c3%a9s" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">Guide bonnes pratiques de création GPG</a>
&rdquo; <em>(cf : le chapitre  &ldquo;Transformons nos clés&rdquo;)</em>,
nous avons abordé le point de la transformation des clés &ldquo;primaires&rdquo;… juste avant
j&rsquo;avais rappelé la nécessité d&rsquo;exporter vos clés. <br>
<em>J&rsquo;espère que vous l&rsquo;avez bel et bien fait !</em></p>
<p>Nous allons utiliser les fichiers exportés des clés publiques et privés, afin de
révoquer les sous-clés relatives…</p>
<p><code>$ gpg --import ~/.gnupg/email@domain.tld.public_key.asc ~/.gnupg/email@domain.tld.private_key.asc</code></p>
<p><em>Bien-sûr, si ces fichiers de clés sont dans un autre chemin, indiquez le bon
répertoire, et le bon nom de fichier.</em> ;-)</p>
<p>Maintenant, nous révoquons nos sous-clés :</p>
<pre tabindex="0"><code>:$ gpg --edit-key email@domain.tld
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
sub  4096R/********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; key1


pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
sub  4096R/********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; key2


pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
sub  4096R/********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; revkey


Do you really want to revoke the selected subkeys? (y/N) y

Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
Your decision? 1

Enter an optional description; end it with an empty line:
&gt;
Reason for revocation: Key is no longer used
(No description given)
Is this okay? (y/N) y


You need a passphrase to unlock the secret key for
user: &#34;Nom Prenom &amp;lt;email@domain.tld&gt;&#34;
4096-bit RSA key, ID ********, created 2013-03-13

**demande votre passhphrase**


You need a passphrase to unlock the secret key for
user: &#34;Nom Prenom &amp;lt;email@domain.tld&gt;&#34;
4096-bit RSA key, ID ********, created 2013-03-13

**demande votre passhphrase une deuxième fois**


pub  4096R/********  created: 2013-03-13  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
This key was revoked on 2013-03-13 by RSA key ******** Nom Prenom
sub  4096R/********  created: 2013-03-13  expires: never       usage: E
This key was revoked on 2013-03-13 by RSA key ******** Nom Prenom
sub  4096R/*********  created: 2013-03-13  expires: never       usage: S
[ultimate] (1). Nom Prenom &amp;lt;email@domain.tld&gt;
[ultimate] (2)  [jpeg image of size 5324]

gpg&gt; save
</code></pre><h2 id="publier">Publier</h2>
<p>Ne pas oublier la phase importante qu&rsquo;est celle d&rsquo;annoncer au monde entier que
votre clé ou vos sous-clés sont révoquées, en la publiant sur un des serveurs SKS.</p>
<p>Là, je vous renvoie à la lecture de mon
<strong><a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/#partagez-votre-cl%c3%a9-publique" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">Guide bonnes pratiques de création GPG</a>
</strong>, sus-nommé, au chapitre
&ldquo;<strong>Partagez votre clé publique !</strong>&rdquo;</p>
<h2 id="de-bonnes-lectures">De bonnes lectures</h2>
<p>Je rappelle de bonnes lectures, qui m&rsquo;ont inspiré, bien-sûr ce mémo :</p>
<ul>
<li>l&rsquo;article d&rsquo;Alex Cabal : &ldquo;<a href="https://alexcabal.com/creating-the-perfect-gpg-keypair/%7C" rel="external">Creating the perfect GPG keypair</a>&rdquo;</li>
<li>le guide &ldquo;<a href="https://guide.boum.org/tomes/2_en_ligne/3_outils/07_utiliser_openpgp/04_creer_et_maintenir_une_paire_de_cles/" rel="external">Créer et maintenir une paire de clés</a> - tome 2 du Guide d&rsquo;autodéfense numérique&rdquo;</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Tutoriel pour révoquer une clé GPG]]></summary>
        <published>2017-07-23T19:38:00+01:00</published>
        <updated>2018-03-04T23:59:06+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b8559d7a-bdec-87f5-06ad-dca3cb8323c3</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/ssl/letsmonitor/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: LetsMonitor.org : monitorer ses certificats LetsEncrypt</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SSL" scheme="http://doc.huc.fr.eu.org/fr/tags/ssl/" />
        <category term="supervision" scheme="http://doc.huc.fr.eu.org/fr/tags/supervision/" />
        <category term="certificat" scheme="http://doc.huc.fr.eu.org/fr/tags/certificat/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Dans le coin, nous avons plus ou moins entendu parler, et nous l&rsquo;utilisons
plus ou moins, comme service SSL, je veux bien sûr parler de <a href="https://letsencrypt.org" rel="external">LetsEncrypt</a>
et de ses certificats.</p>
<p>Maintenant, il est possible de les &ldquo;monitorer&rdquo;, et pour cela, c&rsquo;est <a href="https://letsmonitor.org" rel="external">LetsMonitor.org</a>.</p>
<p>La première chose à faire est de s&rsquo;enregistrer. <br>
Ensuite, lors de la première connexion, l&rsquo;interface demande de créer un &ldquo;contact&rdquo;.
Il est possible d&rsquo;en créer plusieurs… <br>
Profitez-en pour tester si l&rsquo;alerte fonctionne, en appuyant sur le bouton
[ Test ] situé sur la même ligne, et dans la colonne &ldquo;Action&rdquo;.</p>
<p>Ensuite, il faut créer son premier moniteur : cliquez sur le lien &ldquo;Certificates&rdquo;,
et renseignez le nom du Moniteur, celui du domaine relatif, et n&rsquo;oubliez
pas de lui attribuer un des contacts précédemment créé.</p>
<p>Le suivi se fait en cliquant sur le lien &ldquo;Dashboard&rdquo;. <br>
Et, profitez du verdict visuel… qui vous indique le nombre de jours
restant, et par code couleurs :</p>
<ul>
<li><strong><span class="green">vert</span>
</strong> : on a le temps :D</li>
<li><strong><span class="orange">orange</span>
</strong> : il ne reste plus que quelques
jours, voire quelques heures… avant que le site ne soit plus accessible.</li>
<li><strong><span class="red">rouge</span>
</strong> : au secours, il est urgent de le
changer où le site ne sera plus accessible</li>
</ul>
<p>Voilà, c&rsquo;est très facile à configurer… et vous recevrez en temps opportun
l&rsquo;alerte nécessaire, selon le médium désiré, par courriel, ou SMS !</p>
<hr>
<p>J&rsquo;en profite pour rappeler que le robot de création s&rsquo;appelle dorénavant <a href="https://certbot.org" rel="external">certbot</a>…</p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Surveiller ses certificats SSL fait avec la CA LetsEncrypt avec le service web LetsMonitor.org]]></summary>
        <published>2017-07-23T19:19:22+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:19faea59-63c7-b6fc-26b0-244166ead9e5</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/php/php-snmp-cannot-adopt-oid-in-snmp/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: PHP SNMP Cannot adopt OID in *-SNMP-*</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="PHP" scheme="http://doc.huc.fr.eu.org/fr/tags/php/" />
        <category term="SNMP" scheme="http://doc.huc.fr.eu.org/fr/tags/snmp/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un très petit mémo pour ceux qui ont cette erreur PHP :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>php-fpm7.1<span style="color:#5bc4bf">[</span>24419<span style="color:#5bc4bf">]</span>: Cannot adopt OID in NET-SNMP-AGENT-MIB: nsNotifyShutdown ::<span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span> netSnmpNotifications <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>php-fpm7.1<span style="color:#5bc4bf">[</span>24419<span style="color:#5bc4bf">]</span>: Cannot adopt OID in NET-SNMP-AGENT-MIB: nsNotifyRestart ::<span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span> netSnmpNotifications <span style="color:#f99b15">3</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>php-fpm7.1<span style="color:#5bc4bf">[</span>24419<span style="color:#5bc4bf">]</span>: Cannot adopt OID in UCD-SNMP-MIB: laErrMessage ::<span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span> laEntry <span style="color:#f99b15">101</span> <span style="color:#5bc4bf">}</span>
</span></span><span style="display:flex;"><span>php-fpm7.1<span style="color:#5bc4bf">[</span>24419<span style="color:#5bc4bf">]</span>: Cannot adopt OID in UCD-SNMP-MIB: laErrorFlag ::<span style="color:#5bc4bf">=</span> <span style="color:#5bc4bf">{</span> laEntry <span style="color:#f99b15">100</span> <span style="color:#5bc4bf">}</span>
</span></span></code></pre></div><p>Soit vous enlevez les modules SNMP de PHP, ce qui pour Debian, ou Ubuntu donne :</p>
<p><code>apt purge $(dpkg -l | awk '/php(.*)-snmp/ { print $2 }')</code></p>
<p>Soit vous installez le package relatif à SNMP :</p>
<p><code>apt install snmp</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Un petit mémo - astuce - pour résoudre l&#39;erreur SNMP &#39;Cannot adopt OID in&#39; avec PHP]]></summary>
        <published>2017-07-23T18:53:13+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ab7b8a45-0a7f-9128-d6f9-95989b63107f</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/sql/mysql-mariadb-innodb-error-log-sequence-number-is-in-the-future/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MySQL/MariaDB : &#39;InnoDB: Error: log sequence number is in the future&#39;</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SQL" scheme="http://doc.huc.fr.eu.org/fr/tags/sql/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici un petit truc et astuce, si dans vos log, vous avez le message
d&rsquo;erreur suivant :</p>
<p><code>InnoDB: Error: page 3 log sequence number 43384293 is in the future! Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDB log files</code></p>
<p>Commencez par vérifier que vos bases sont dans un état correct avec
l&rsquo;outil <code>myslqcheck</code>.</p>
<p>Le moyen le plus facile est :</p>
<ul>
<li>de purger les bases de données,</li>
<li>vérifier la bonne destruction…</li>
<li>puis de réinstaller une sauvegarde &ldquo;propre&rdquo; !</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre l&#39;erreur &#39;InnoDB: Error: log sequence number is in the future&#39; dans MySQL/MariaDB]]></summary>
        <published>2017-07-23T18:50:15+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:50cf2487-ceb4-1a9e-0125-b93983588bf8</id>
        <link href="http://doc.huc.fr.eu.org/fr/web/sql/mysql-mariadb-innodb-cannot-open-table/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: MySQL/MariaDB : &#39;InnoDB: Cannot open table&#39;</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="SQL" scheme="http://doc.huc.fr.eu.org/fr/tags/sql/" />
        <category term="InnoDB" scheme="http://doc.huc.fr.eu.org/fr/tags/innodb/" />
        <category term="Erreur" scheme="http://doc.huc.fr.eu.org/fr/tags/erreur/" />
        <category term="astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Voici un autre petit truc et astuce, si dans vos log, vous avez le message
d&rsquo;erreur suivant :</p>
<p><code>[Warning] InnoDB: Cannot open table mysql/gtid_slave_pos from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/ ... oting.html for how you can resolve the problem.</code></p>
<p>Ce message d&rsquo;erreur peut-être à-propos des tables :</p>
<ul>
<li><code>mysql/gtid_slave_pos</code></li>
<li><code>mysql/innodb_index_stats</code></li>
<li><code>mysql/innodb_table_stats</code></li>
</ul>
<p>D&rsquo;autres tables peuvent être concernées !</p>
<p>Sachez que c&rsquo;est une erreur qui arrive, généralement, après une mise-à-jour du
serveur !</p>
<h2 id="dépannage">Dépannage</h2>
<p>La meilleure manière de le résoudre est :</p>
<ul>
<li>de <strong>supprimer les fichiers .frm et .idb relatifs à ces tables</strong>, non
mises-à-jour correctement.</li>
<li>d&rsquo;<strong>arrêter le serveur, puis le démarrer</strong> - et <em>non pas redémarrer</em> le serveur !</li>
<li>d&rsquo;exécuter, en suivant, l&rsquo;outil <code>mysql_upgrade</code> avec l&rsquo;option <code>--force</code>
par le compte administrateur de MySQL/MariaDB, tel que : <br>
<code># mysql_upgrade --force -u admin_db -p</code></li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Il est possible de trouver des scripts qui vous disent d&rsquo;injecter le code
SQL pour recréer les tables défectueuses de la base de données mysql -
<strong>ne le faites pas ; privilégiez vraiment la méthode ci-dessus</strong> !</div>

<hr>
]]></content>
        <summary type="html"><![CDATA[Résoudre l&#39;erreur &#39;InnoDB: Cannot open table&#39; pour MySQL/MariaDB]]></summary>
        <published>2017-07-23T18:49:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:28981bfb-c529-a1c1-18d6-d8a9465c5cb4</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/linux/durcir-iommu/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Durcir Linux : Forcer l&#39;IOMMU</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Harden" scheme="http://doc.huc.fr.eu.org/fr/tags/harden/" />
        <category term="IOMMU" scheme="http://doc.huc.fr.eu.org/fr/tags/iommu/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Mais qu&rsquo;est donc l&rsquo;IOMMU ? <strong>Input/Output Memory Management Unit</strong> <br>
<em>en français, <strong>Unité de Gestion des Entrées/Sorties en Mémoire</strong></em></p>
<p>C&rsquo;est une sorte de pare-feu matériel, pour les ports PCI, et VGA.</p>
<h3 id="architectures-concernées">Architectures concernées</h3>
<ul>
<li><strong><a href="https://www.kernel.org/doc/Documentation/Intel-IOMMU.txt" rel="external">Intel</a></strong> - dont l&rsquo;option <strong><abbr title="Virtualization Technology for Directed Input/Output">VT-d</abbr>
</strong>
doit être activée dans le BIOS, ainsi que sa prise-en-charge dans le kernel.</li>
<li><strong><a href="http://developer.amd.com/wordpress/media/2012/10/IOMMU-ben-yehuda.pdf" rel="external">AMD</a></strong> a aussi son propre mode <strong>AMD-V</strong> pour <em><strong>I/O Virtualization Technology</strong></em>,
ou <strong><abbr title="Secure Virtual Machine">SVM</abbr>
</strong>, ainsi que <strong><abbr title="Graphical Aperture Remapping Table">GART</abbr>
</strong>
pour gérer les cartes AGP, et fonctionnels avec les CPU AMD Opteron,
AMD Athlon 64, AMD Turion 64…</li>
<li><strong>IBM</strong> a la sienne : <strong>Calgary PCI-X</strong></li>
<li><strong><a href="http://www.arm.com/products/system-ip/controllers/system-mmu.php" rel="external">ARM</a></strong> a sa propre unité appelée <strong><abbr title="System Memory Management Unit">SSMU</abbr>
</strong></li>
<li>XenServer a sa propre fonction &ldquo;<strong>PCI passthrough</strong>&rdquo; ou l&rsquo;équivalent
pour les cartes VGA, à savoir &ldquo;<strong>VGA passthrough</strong>&rdquo; &hellip;</li>
</ul>
<h2 id="configuration">Configuration</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">L&rsquo;activation de l&rsquo;IOMMU peut engendrer des instabilités matérielles. <br>
À surveiller et à désactiver si c&rsquo;est le cas !</div>

<p>Hormis le fait de posséder l&rsquo;une des architectures sus-nommées, il vous
faut avoir à minima un kernel <strong>Linux 2.6</strong>…</p>
<p>activez l&rsquo;option dans le BIOS de votre machine !</p>
<p>Vous pouvez forcer son usage, ce qui est recommandé, en éditant votre fichier :</p>
<ul>
<li><code>/etc/defaut/grub</code></li>
<li><code>/boot/grub/menu.lst</code></li>
<li>et en ajoutant l&rsquo;option <code>iommu=force</code> sur la ligne <code>GRUB_CMDLINE_LINUX</code>…</li>
</ul>
<p>Mettez à jour <code>grub</code> !</p>
<h2 id="documentation">Documentation</h2>
<p>⇒ Un très bon <a href="https://www.sstic.org/media/SSTIC2010/SSTIC-actes/Analyse_de_l_efficacite_du_service_fourni_par_une_/SSTIC2010-Article-Analyse_de_l_efficacite_du_service_fourni_par_une_IOMMU-lacombe_lone-sang_nicomette_deswarte.pdf" rel="external">document</a> a été écrit pour le <abbr title="Symposium sur la sécurité des technologies de l'information et des communications">SSTIC</abbr>

en 2010, à ce propos en disant de celle-ci :</p>
<blockquote>
Il s'agit d'un composant matériel qui agit comme un pare-feu et filtre
les accès en provenance des périphériques vers la mémoire principale. \
(…) est un composant matériel permettant à un système d'exploitation de
contrôler l'accès des périphériques à la mémoire principale.
</blockquote>
<p>Ce document nommé &ldquo;<strong>Analyse de l&rsquo;efficacité du service fourni par une IOMMU</strong>&rdquo;
décrit comment cette unité de gestion matérielle interagit avec le système
GNU/Linux, et comment malheureusement il est possible de la &ldquo;leurrer&rdquo; pour
mener des attaques réseaux, par exemple, à partir d&rsquo;une interface Firewire,
mais aussi mène à réfléchir sur son bon usage.</p>
<p>⇒ Un autre <a href="https://www.sstic.org/media/SSTIC2016/SSTIC-actes/dma_bypass_with_dma/SSTIC2016-Article-dma_bypass_with_dma-morgan_alata_averlant_nicomette.pdf" rel="external">document</a> démontrant une attaque possible par le biais d&rsquo;une
interface FPGA sur PCI-E.</p>
<p>⇒ Une troisième source d&rsquo;informations intéressantes : Le &ldquo;<strong><a href="http://www.ssi.gouv.fr/uploads/2015/10/NP_Linux_Configuration.pdf" rel="external">NP Linux Configuration</a></strong>&rdquo; !</p>
<h3 id="wikipedia">Wikipedia</h3>
<ul>
<li><a href="https://en.wikipedia.org/wiki/List_of_IOMMU-supporting_hardware" title="Article Wikipédia : List_of_IOMMU-supporting_hardware">List_of_IOMMU-supporting_hardware <sup><abbr class="is-italic" title="Wikipedia">WP</abbr></sup></a>
 : liste de matériels gérant IOMMU.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment sécuriser sa distribution GNU/Linux en modifiant l&#39;IOMMU]]></summary>
        <published>2017-07-23T17:41:36+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a8f796d4-a76a-7dbf-146c-ce91fa4a1038</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/chkrootkit-possible-linux-ebory-operation-windigo/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Chkrootkit : Possible Linux Ebory Operation Windigo Installed</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="chkrootkit" scheme="http://doc.huc.fr.eu.org/fr/tags/chkrootkit/" />
        <category term="Linux" scheme="http://doc.huc.fr.eu.org/fr/tags/linux/" />
        <category term="Ebury" scheme="http://doc.huc.fr.eu.org/fr/tags/ebury/" />
        <category term="Windigo" scheme="http://doc.huc.fr.eu.org/fr/tags/windigo/" />
        <category term="SSH" scheme="http://doc.huc.fr.eu.org/fr/tags/ssh/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <category term="intrusion" scheme="http://doc.huc.fr.eu.org/fr/tags/intrusion/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Chkrootkit émet cette alerte :
<q>Searching for Linux/Ebury - Operation Windigo ssh&hellip;
Possible Linux/Ebury - Operation Windigo installetd</q></p>
<p><strong>Déjà, si votre installation est fraîche, ne paniquez pas ; de toute façon,
cela ne sert jamais à rien !</strong></p>
<p>Ne paniquez pas si vous venez de mettre-à-jour vers Ubuntu - <em>cela touche
les versions 15.10, 16.04 LTS - ( et toutes les distributions basées dessus,
telle que Linux Mint)</em> ;
et, idem si vous avez eu la bêtise de passer de votre version stable de Debian
à une Testing, ou si vous avez fait des màj sur votre Sid !</p>
<p>En effet ce rootkit Ebury, qui sévit depuis 2014, modifie la librairie &ldquo;<strong>libkeyutils</strong>&rdquo;
pour ajouter une option <code>-G</code> au binaire SSH, et/ou remplace les binaires
liés au projet OpenSSH, tels que ssh, ssh-add, etc… <br>
ce qui permet la prise de contrôle à distance et surtout le vol de données.</p>
<hr>
<p><strong>SAUF que depuis la <a href="http://www.openssh.com/txt/release-6.8" rel="external">version 6.8 d&rsquo;OpenSSH</a>, l&rsquo;option &lsquo;-G&rsquo; existe !</strong> <br>
<em>(c&rsquo;est même un alias de l&rsquo;option <code>-T</code>)</em></p>
<blockquote cite="http://www.openssh.com/txt/release-6.8">
ssh(1): Add a -G option to ssh that causes it to parse its configuration and dump the result to stdout, similar to "sshd -T".
</blockquote>
<p>Ce qui fausse le résultat de détection de chkrootkit !</p>
<p>De même la commande suivante fausse le résultat si vous avez une version
supérieure ou égale à la 6.8 d&rsquo;OpenSSH  :</p>
<p><code>$ ssh -G 2&gt;&amp;1 | grep -e illegal -e unknown &gt; /dev/null &amp;&amp; echo “System clean” || echo “System infected”</code></p>
<hr>
<p>De plus, sachez qu&rsquo;il existe une déclaration de bogue de faux positif :</p>
<ul>
<li>pour Debian, #<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=796599" rel="external">796599</a>, résolu à ce jour… corrigé dans la version 0.50-4</li>
<li>pour Ubuntu, #<a href="https://bugs.launchpad.net/ubuntu/+source/chkrootkit/+bug/1508248" rel="external">1508248</a>…</li>
</ul>
<p>Alors comment savoir si c&rsquo;est un faux positif ou non !?</p>
<h2 id="analyse">Analyse</h2>
<h3 id="analyse-de-shm">Analyse de SHM</h3>
<p>Commençons par analysez votre mémoire partagée SHM, par le biais de la
commande <code># ipcs -m</code>… avec des droits admin.</p>
<ul>
<li>Si vous n&rsquo;avez aucun retour, tant mieux…</li>
<li>sinon, il faut chercher à comprendre ce qu&rsquo;une telle sortie peut signifier :
<ul>
<li>Si vous avez un processus &lsquo;root&rsquo;, avec un mode 0666 ou 0600, et une
taille au moins égale à 3 Mo, vous avez une forte probabilité
d&rsquo;être concerné !</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# ipcs -m
</span></span><span style="display:flex;"><span>------ Shared Memory Segments --------
</span></span><span style="display:flex;"><span>key  shmid owner perms bytes  nattch
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>0x000010e0    <span style="color:#f99b15">465272836</span>   root   <span style="color:#f99b15">666</span>   <span style="color:#f99b15">3282312</span>   <span style="color:#f99b15">0</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# ipcs -m -p
</span></span><span style="display:flex;"><span>------ Shared Memory Creator/Last-op PIDs --------
</span></span><span style="display:flex;"><span>shmid    owner     cpid     lpid
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>...<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span><span style="color:#f99b15">465272836</span>    root    <span style="color:#f99b15">15029</span>    <span style="color:#f99b15">17377</span>
</span></span></code></pre></div><p>Vérifier qu&rsquo;un tel processus fonctionne - <em>remplacez par le numéro de
<abbr title="processus identifiant">pid</abbr>

que vous avez trouvé</em> - en interrogeant <code>ps</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>:# ps aux | grep <span style="color:#f99b15">15029</span>
</span></span><span style="display:flex;"><span>root <span style="color:#f99b15">11531</span> 0.0 0.0 <span style="color:#f99b15">103284</span> <span style="color:#f99b15">828</span> pts/0 S+ 16:40 0:00 grep <span style="color:#f99b15">15029</span>
</span></span><span style="display:flex;"><span>root <span style="color:#f99b15">15029</span> 0.0 0.0 <span style="color:#f99b15">66300</span> <span style="color:#f99b15">1204</span> ? Ss Jan26 0:00 /usr/sbin/sshd
</span></span></code></pre></div><p>Le processus en question étant identifié comme <strong>ssh</strong>, c&rsquo;est un très bel
indicateur de compromission !</p>
<p><strong>Pas la peine d&rsquo;aller plus loin, si c&rsquo;est malheureusement votre cas</strong>…  &#x1f61f;  &#x1f627;</p>
<h3 id="analyse-des-fichiers">Analyse des fichiers</h3>
<ol>
<li>Vérifions la taille de tous les fichiers dont le nom commence par
<code>libkeyutils.so</code> dans le répertoire <code>/lib</code> : <br>
<code># find /lib* -type f -name libkeyutils.so* -exec ls -la {} \;</code> <br>
<code>-rw-r--r-- 1 root root 14256 Dec 10  2015 /lib/x86_64-linux-gnu/libkeyutils.so.1.5</code></li>
</ol>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert">Si la taille des fichiers est supèrieure à 25 kilobytes, votre système est
corrompu !</div>

<ol start="2">
<li>Recherchons la présence non désirable d&rsquo;une autre bibliothèque partagée,
dans le répertoire <code>/lib</code>, appelée <code>libns2.so</code> : <br>
<code># find /lib* -type f -name libns2.so</code> <br>
<strong>Sur un système sain, la commande ne retourne rien !</strong></li>
</ol>
<h3 id="analyse-réseau">Analyse réseau</h3>
<ol>
<li>
<p>L&rsquo;usage du binaire <strong>netstat</strong> nous permet de nous assurer d&rsquo;un flux non désiré : <br>
<code># netstat -nap | grep &quot;@/proc/udevd&quot;</code> <br>
<strong>Sur un système sain, vous n&rsquo;aurez absolument aucun retour !</strong></p>
</li>
<li>
<p>L&rsquo;autre binaire qui permet de s&rsquo;assurer d&rsquo;un flux sain, est l&rsquo;usage de
la commande <code>tcpdump -p</code>… qui peut vous dévoiler des informations, telles que : <br>
&ldquo;msg:”Linux/Ebury SSH backdoor data exfiltration…&rdquo; <br>
néanmoins, cela n&rsquo;est malheureusement pas probant, puisque les récentes
versions du rootkit tendent à cacher ce genre d&rsquo;informations !</p>
</li>
</ol>
<h3 id="résultat">Résultat</h3>
<p>Si votre système est bel et bien sain, malgré le message de l&rsquo;outil chkrootkit,
tant mieux. Il va vous falloir attendre que le binaire soit corrigé, vous
avez donc bel et bien affaire au faux positif. En attendant, continuez de vérifier…</p>
<p>Dans le cas contraire, <strong>la seule recommandation valable est la réinstallation
complète du système</strong>. Profitez-en pour vérifiez que vos stations ne soient pas
infectées !</p>
<p>Une fois fait, <strong>ne réutilisez pas les mêmes mots-de-passe</strong>,
<strong>changez toutes vos clés SSH</strong>, et profitez pour en

<a class="inside" href="/fr/sec/ssh/configuration-securisee/" title="Lien interne vers l&#39;article : 'SSH : Configuration Sécurisée'">créer correctement des clés SSH fortes</a>
…</p>
<h2 id="documentation">Documentation</h2>
<p>Si vous avez besoin/voulez plus d&rsquo;informations sur ce rootkit, il y a deux
lectures très intéressantes, en anglais - <em>les informations que je vous
restitue en sont tirées</em> - :</p>
<ul>
<li>Ebury SSH Rootkit - <a href="https://www.cert-bund.de/ebury-faq" rel="external">Frequently Asked Questions</a> du CERT Bund</li>
<li><a href="http://www.welivesecurity.com/wp-content/uploads/2014/03/operation_windigo.pdf" rel="external">OPERATION WINDIGO</a> où l&rsquo;on découvre que plus d&rsquo;un OS est affecté, de Linux à *BSD !</li>
</ul>
<p>Pour information, à ce jour, les outils <strong>rkhunter</strong> et <strong>clamav</strong> ne seraient
pas capables de le détecter…</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Que faire en cas de message de chkrootkit : Possible Linux/Ebury - Operation Windigo installed ?]]></summary>
        <published>2017-07-23T17:23:16+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:630b46ac-2e0d-b831-df65-e20f50974752</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/lynis-pkgs-7346-purge-packages/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Lynis : Purge old/removed packages [PKGS-7346]</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Lynis" scheme="http://doc.huc.fr.eu.org/fr/tags/lynis/" />
        <category term="packages" scheme="http://doc.huc.fr.eu.org/fr/tags/packages/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un petit mémo concernant la complainte de Lynis : <br>
<q>Purge old/removed packages (x found) with aptitude purge or dpkg &ndash;purge command. This will cleanup old configuration files, cron jobs and startup scripts. [ <a href="https://cisofy.com/controls/PKGS-7346/" rel="external">PKGS-7346</a> ]</q></p>
<p>C&rsquo;est sa manière de dire qu&rsquo;il reste des traces de configurations de paquets/binaires qui ont été désinstallés.</p>
<h2 id="vérification">Vérification</h2>
<p>Sur Debian, Ubuntu, et assimilées - <em>cela vous permet de vous assurer des paquets qui ont été supprimés, dont il reste les fichiers de configuration</em> - :</p>
<p><code>$ dpkg --get-selections | awk '/deinstall/ { print $1 }'</code></p>
<h2 id="purge">Purge</h2>
<p>Sur Debian, Ubuntu, et consorts :</p>
<p>⇒ avec <strong>apt</strong> : <br>
<code># apt purge  $(dpkg --get-selections | awk '/deinstall/ { print $1 }')</code></p>
<p>⇒ avec <strong>dpkg</strong> : <br>
<code># dpkg --purge $(dpkg --get-selections | awk '/deinstall/ { print $1 }')</code></p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre la suggestion de l&#39;outil de détection Lynis : Purge old/removed packages [PKGS-7346]]]></summary>
        <published>2017-07-23T17:05:44+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:e625c548-d94d-773f-2798-8dfe4ae3a1a2</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/lynis-auth-9328-default-umask-like-027/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Lynis : Default umask like 027 [AUTH-9328]</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Lynis" scheme="http://doc.huc.fr.eu.org/fr/tags/lynis/" />
        <category term="auth" scheme="http://doc.huc.fr.eu.org/fr/tags/auth/" />
        <category term="umask" scheme="http://doc.huc.fr.eu.org/fr/tags/umask/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Mémo à-propos de la suggestion de Lynis : <q>Default umask in /etc/init.d/rc could be more strict like 027 [ <a href="https://cisofy.com/controls/AUTH-9328/" rel="external">AUTH-9328</a> ]</q></p>
<p>En effet le <strong><a href="http://www.ssi.gouv.fr/uploads/2015/10/NP_Linux_Configuration.pdf" rel="external">Guide de Recommandations d&rsquo;un Système GNU/Linux</a></strong> de l&rsquo;ANSSI, au chapitre 6.1.5 Umask, nous rappelle à juste titre que :</p>
<ul>
<li>la valeur <code>0022</code> est considérée très permissive,</li>
<li>que le <strong><code>umask</code> système</strong> régit par le fichier <code>/etc/init.d/rc</code> doit
être positionné sur <code>0027</code>, ce qui fige les droits permissifs, tels
que lecture autorisée pour l&rsquo;utilisateur et son groupe, et modifiable
uniquement par son créateur.</li>
</ul>
<p>Il faut modérer le fait que pour toutes les distributions systemd, tels
que sont maintenant la plupart des Debian, et Ubuntu, il faut modifier
le masque système dans le propre fichier de configuration du service à
configurer.</p>
<p><code># sed -i -e &quot;s#umask 022#umask 027#&quot; /etc/init.d/rc</code></p>
<p>Tant qu&rsquo;à faire, profitons-en pour modifier la valeur du <strong><code>umask</code> utilisateurs</strong>
qui doit être paramétré à <code>077</code> !</p>
<ul>
<li>Pour les distributions systemd, c&rsquo;est le fichier <code>/etc/profile</code>.</li>
<li>Pour les distributions non systemd, c&rsquo;est le fichier <code>/etc/login.defs</code>.</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION : Il est impératif de vérifier à chaque
mise-à-jour de version de distribution, car ces droits seront réinitialisés
par défaut !</strong></div>

<hr>
]]></content>
        <summary type="html"><![CDATA[Comment résoudre la suggestion de l&#39;outil de détection Lynis : Default umask like 027 [AUTH-9328]]]></summary>
        <published>2017-07-23T17:00:00+02:00</published>
        <updated>2020-10-10T00:18:56+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8e138c78-cf11-a148-cd92-901b08c33a39</id>
        <link href="http://doc.huc.fr.eu.org/fr/sec/scan/rkhunter/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rkhunter</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="rkhunter" scheme="http://doc.huc.fr.eu.org/fr/tags/rkhunter/" />
        <category term="detection" scheme="http://doc.huc.fr.eu.org/fr/tags/detection/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<ul>
<li>rkhunter: <a href="http://rkhunter.sourceforge.net" rel="external">http://rkhunter.sourceforge.net</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Sur une Debian, *Buntu <em>(et assimilée)</em>, avec des droits administrateurs : <br>
<code># apt install rkhunter</code></p>
<h2 id="configuration">Configuration</h2>
<h3 id="etcrkhunterconf">/etc/rkhunter.conf</h3>
<p>Très classiquement, il faut <strong>éditer le fichier</strong> <code>/etc/rkhunter.conf</code>,
toujours <strong>avec les droits administrateurs</strong>, pour changer quelques informations.</p>
<ul>
<li>Sur Debian : <code>MAIL-ON-WARNING=yourmail@yourdomain.com</code></li>
<li>Sur Ubuntu : <code>MAIL-ON-WARNING=&quot;yourmail@yourdomain.com&quot;</code></li>
<li>Sur Ubuntu, pour une gestion liée à gestionnaire de paquets : <code>PKGMGR=DPKG</code></li>
</ul>
<h3 id="etcdefaultrkhunter">/etc/default/rkhunter</h3>
<p>L&rsquo;autre fichier à éditer est le fichier <code>/etc/default/rkhunter</code> :</p>
<p><code>CRON_DAILY_RUN=&quot;true&quot;</code>, et <br>
<code>REPORT_EMAIL=&quot;yourmail@yourdomain.net&quot;</code></p>
<h2 id="utilisation">Utilisation</h2>
<p>Ceci étant fait, voici les différentes possibilités de l&rsquo;utiliser :</p>
<ul>
<li><strong>Pour vérifier</strong>, avec l&rsquo;option <code>-c</code>, <code>--check</code> ou <code>--checkall</code> - <em>ces
deux dernières options sont dépendantes de la version de rkhunter !</em></li>
<li><strong>Pour mettre-à-jour rkhunter</strong>, utilisez l&rsquo;option <code>--update</code>.</li>
<li><strong>Pour mettre-à-jour la base de donnée</strong>, après un changement dans la
configuration du fichier <code>/etc/rkhunter.conf</code>, utilisez l&rsquo;option <code>--propupd</code>.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<h3 id="manpage">Manpage</h3>
<ul>
<li>Pour en savoir plus, un coup de <code>man rkhunter</code> dans votre terminal console,
vous en apprendra beaucoup plus…</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Installation et configuration de l&#39;outil de détection des rootkits rkhunter]]></summary>
        <published>2017-07-20T13:10:37+02:00</published>
        <updated>2020-10-12T20:03:36+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:3f2cd36e-3f4d-24a6-d1fb-b28093d20c14</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/openbsd-libreboot/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Installer LibertyBSD ou OpenBSD sur un système libreboot</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Libreboot" scheme="http://doc.huc.fr.eu.org/fr/tags/libreboot/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article dispary
&ldquo;<strong><a href="https://web.archive.org/web/20161014161119/https://libreboot.org/docs/bsd/openbsd.html" rel="external">How to install LibertyBSD or OpenBSD on a libreboot system</a></strong>&rdquo;,
écrit sur le site &lsquo;Libreboot.org&rsquo;.</p>
<hr>
<h1 id="installer-libertybsd-ou-openbsd-sur-un-système-libreboot">Installer LibertyBSD ou OpenBSD sur un système libreboot</h1>
<p>NOTE : Ce guide a été écrit pour OpenBSD par la personne qui a contribué,
mais le projet libreboot recommande LibertyBSD. LibertyBSD est une
version d&rsquo;OpenBSD sans logiciel propriétaire dans les dépôts ( OpenBSD
distribue les micro-programmes blob pour les périphériques à l&rsquo;intérieur
du noyau ). Allez sur le <a href="http://libertybsd.net/" rel="external">site web de LibertyBSD</a></p>
<p>À FAIRE : testez sur LibertyBSD en priorité dans ce guide.</p>
<p>Cette section relate la préparation, le démarrage et l&rsquo;installation
d&rsquo;OpenBSD sur votre système libreboot, n&rsquo;utilisant rien de plus qu&rsquo;une
clé USB (et <code>dd</code>). Cette procédure a été testée seulement sur un Lenovo
ThinkPad x200.</p>
<p>Cette section est seulement en rapport avec GRUB. Pour
<del>depthcharge</del> (utilisé sur les périphériques CrOS dans libreboot),
les instructions doivent encore être écrites dans la documentation de
libreboot.</p>
<p>install60.fs est l&rsquo;image d&rsquo;installation d&rsquo;OpenBSD 6.0. Adaptez le nom du
fichier selon que vous utilisez une version différente d&rsquo;OpenBSD ou
LibertyBSD.</p>
<h2 id="préparer-le-périphérique-usb-dans-libertybsd-ou-openbsd">Préparer le périphérique USB (dans LibertyBSD ou OpenBSD)</h2>
<p>Si vous avez téléchargé votre ISO d&rsquo;un système LibertyBSD ou OpenBSD,
voici comment créer un périphérique USB de LibertyBSD/OpenBSD démarrable :</p>
<p>Connectez le périphérique USB. Vérifiez dmesg :</p>
<p><code>$ dmesg | tail</code></p>
<p>Vérifiez pour confirmer quelle unité de disque est utilisée, par exemple,
si vous pensez que cela est <code>sd3</code> :</p>
<p><code>$ disklabel sd3</code></p>
<p>Vérifiez qu&rsquo;il n&rsquo;a pas été monté automatiquement. Si cela était le cas,
démontez-le. Par exemple :</p>
<p><code>$ doas umount /dev/sd3i</code></p>
<p><code>dmesg</code> vous dit quel est le périphérique. Écrasez le lecteur, en
écrivant l&rsquo;installeur d&rsquo;OpenBSD avec <code>dd</code>. Par exemple :</p>
<p><code>$ doas dd if=install60.fs of=/dev/rsdXc bs=1M; sync</code></p>
<p>Vous devriez maintenant être capable de démarrer l&rsquo;installeur depuis
votre périphérique USB. Continuez la lecture, pour information afin de
savoir comment faire.</p>
<h2 id="préparer-le-périphérique-usb-dans-netbsd">Préparer le périphérique USB (dans NetBSD)</h2>
<p><a href="https://wiki.netbsd.org/tutorials/how_to_install_netbsd_from_an_usb_memory_stick/" rel="external">Cette page</a>
sur le site web de NetBSD montre comment créer un périphérique USB
NetBSD démarrable depuis NetBSD lui-même. Vous devriez utiliser la
méthode dd documentée ici. Ceci fonctionne aussi avec l&rsquo;image d&rsquo;OpenBSD.</p>
<h2 id="préparer-le-périphérique-usb-dans-freebsd">Préparer le périphérique USB (dans FreeBSD)</h2>
<p><a href="https://www.freebsd.org/doc/handbook/bsdinstall-pre.html" rel="external">Cette page</a>
sur le site web de FreeBSD montre comment créer un périphérique USB
démarrable pour installer FreeBSD. Utilisez dd sur cette page. Vous
pouvez aussi utiliser les mêmes instructions avec une image ISO d&rsquo;OpenBSD.</p>
<h2 id="préparer-le-périphérique-usb-dans-gnulinux">Préparer le périphérique USB (dans GNU/Linux)</h2>
<p>Si vous avez téléchargé votre ISO sur un système GNU/Linux, voici
comment créer le périphérique USB démarrable d&rsquo;OpenBSD :</p>
<p>Connectez le périphérique USB. Vérifiez dmesg :</p>
<p><code>$ dmesg</code></p>
<p>Vérifiez <code>lsblk</code> pour confirmer quel lecteur est utilisé :</p>
<p><code>$ lsblk</code></p>
<p>Vérifiez qu&rsquo;il n&rsquo;a pas été monté automatiquement. Si cela était,
démontez-le. Par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ sudo umount /dev/sdX<span style="color:#f99b15">\*</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># umount /dev/sdX\*</span>
</span></span></code></pre></div><p><code>dmesg</code> vous dit quel est le périphérique. Écrasez le lecteur, en
écrivant l&rsquo;installeur d&rsquo;OpenBSD avec <code>dd</code>. Par exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ sudo dd <span style="color:#815ba4">if</span><span style="color:#5bc4bf">=</span>install60.fs <span style="color:#ef6155">of</span><span style="color:#5bc4bf">=</span>/dev/sdX <span style="color:#ef6155">bs</span><span style="color:#5bc4bf">=</span>8M; sync
</span></span><span style="display:flex;"><span><span style="color:#776e71"># dd if=install60.fs of=/dev/sdX bs=8M; sync</span>
</span></span></code></pre></div><p>Vous devriez maintenant être capable de démarrer l&rsquo;installeur depuis
votre périphérique USB. Continuez la lecture, pour information afin de
savoir comment faire.</p>
<h2 id="installer-openbsd-sans-chiffrement-du-disque-dur">Installer OpenBSD sans chiffrement du disque dur</h2>
<p>Pressez la touche <code>&lt;kbd&gt;c&lt;/kbd&gt;</code> dans <code>GRUB</code> pour accéder à la ligne de
commande :</p>
<pre tabindex="0"><code class="language-grub" data-lang="grub">grub&gt; kopenbsd (usb0,openbsd1)/6.0/amd64/bsd.rd
grub&gt; boot
</code></pre><p>Cela démarrera l&rsquo;installeur d&rsquo;OpenBSD. Suivez le processus normal pour
installer OpenBSD.</p>
<h2 id="installer-openbsd-avec-le-chiffrement-de-disque-dur">Installer OpenBSD avec le chiffrement de disque dur</h2>
<p>Cela ne fonctionne pas. Vous pouvez modifier la procédure ci-dessus
(celle de l&rsquo;installation sans chiffrement) pour installer OpenBSD en
utilisant le chiffrement de disque dur, et cela semble fonctionner,
excepté que démarrer une installation d&rsquo;OpenBSD + FDE en utilisant
libreboot+Grub2 n&rsquo;est pas clair. Si pour vous cela fonctionne, veuillez
nous le faire savoir.</p>
<p>Si démarrer en mode texte (le mode framebuffer pourrait également
fonctionner aussi), il est possible de charger le chargeur de démarrage
d&rsquo;OpenBSD ou de LibertyBSD depuis le secteur MBR sur le périphérique de
stockage interne. De cette manière, il serait possible de démarrer avec
une installation d&rsquo;OpenBSD ou de LibertyBSD chiffrée. Veuillez nous
faire savoir ( les détails de contact sont sur la page d&rsquo;accueil de
libreboot ) si vous arrivez à le faire fonctionner ainsi.</p>
<p>Alternativement, ce serait une bonne chose de porter OpenBSD à ce qu&rsquo;il
prenne en charge nativement coreboot, ou de porter la libpayload (la
bibliothèque de chargement dans coreboot ;  c&rsquo;est une bibliothèque C
basique et quelques fonctions pour certaines opérations, tel que text/bitmap).
Cela serait idéal, parce qu&rsquo;il serait possible de démarrer vraiment une
installation d&rsquo;OpenBSD ou de LibertyBSD pleinement chiffrée, en mettant
tout dans la puce flash.</p>
<p>Alternativement, modifier GRUB pour supporter le démarrage
d&rsquo;installations d&rsquo;OpenBSD pleinement chiffrées serait possible, mais
probablement pas faisable ; c&rsquo;est une base de code étrangère au projet
OpenBSD, pas bien intégrée, d&rsquo;autant que le chargeur de démarrage
d&rsquo;OpenBSD est déjà fonctionnel.</p>
<h2 id="démarrer">Démarrer</h2>
<p>Pressez la touche <kbd>c</kbd> dans <code>GRUB</code> pour accéder à la ligne de
commande :</p>
<pre tabindex="0"><code class="language-grub" data-lang="grub">grub&gt; kopenbsd -r sd0a (ahci0,openbsd1)/bsd
grub&gt; boot
</code></pre><p>OpenBSD devrait démarrer. Excellent !</p>
<h2 id="configurer-grub">Configurer Grub</h2>
<p>Si vous ne voulez pas utiliser la ligne de commande GRUB et de taper une
commande au démarrage d&rsquo;OpenBSD à chaque fois, vous pouvez créer une
configuration GRUB qui tiendra compte de votre installation d&rsquo;OpenBSD et
qui sera utilisée automatiquement par libreboot.</p>
<p>Sur votre partition racine d&rsquo;OpenBSD, créez le répertoire <code>/grub</code> et
ajoutez-le au fichier <code>libreboot_grub.cfg</code>. Ajoutez ces lignes à
l&rsquo;intérieur de <code>libreboot_grub.cfg</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">default</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0 timeout=3 menuentry &#34;OpenBSD&#34; {</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>     <span style="color:#06b6ef">kopenbsd -r sd0a (ahci0,openbsd1)/bsd </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span></code></pre></div><p>Lors de votre prochain démarrage, vous verrez le menu du vieux Grub
pendant quelques secondes, puis vous verrez le nouveau menu avec
seulement OpenBSD dans la liste. Après 3 secondes OpenBSD démarrera, ou
vous pouvez le sélectionner en appuyant sur la touche <kbd>ENTRÉE</kbd>
pour démarrer.</p>
<h2 id="dépannage">Dépannage</h2>
<p>La plupart de ces problèmes arrivent par l&rsquo;usage de libreboot avec le
mode texte de coreboot en lieu et place du mode framebuffer de coreboot.
Ce mode est utile pour le démarrage de charge utile tel que memtest86+
qui ont besoin du mode texte, mais pour OpenBSD, cela est problématique
lors de la bascule vers le mode framebuffer, car non supporté.</p>
<p>Dans la plupart des cas, vous devriez utiliser les images ROM vesafb.
Exemple de nom de fichier : <code>libreboot_ukdvorak_vesafb.rom</code>.</p>
<h3 id="cela-ne-veut-pas-démarrer-quelque-chose-à-propos-dun-fichier-non">Cela ne veut pas démarrer&hellip; quelque chose à-propos d&rsquo;un fichier non</h3>
<p>trouvé</p>
<p>Vos noms et numéros de périphériques (tels que usb0, usb1, sd0, sd1, wd0,
ahci0, hd0, etc&hellip;) peuvent différer. Utilisez la complétion <kbd>TAB</kbd>.</p>
<hr>
<h2 id="copyright">Copyright</h2>
<p>Copyright © 2016 Scott Bonds <a href="mailto:scott@ggr.com" rel="external">scott@ggr.com</a> <br>
Copyright © 2016 Leah Rowe <a href="mailto:info@minifree.org" rel="external">info@minifree.org</a> <br>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License Version 1.3 or any
later version published by the Free Software Foundation with no Invariant
Sections, no Front Cover Texts, and no Back Cover Texts. A copy of this
license is found in <a href="https://libreboot.org/docs/fdl-1.3.html" rel="external">../fdl-1.3.html</a></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article disparu &#39;How to install LibertyBSD or OpenBSD on a libreboot system&#39; du site &#39;libreboot.org&#39;]]></summary>
        <published>2017-05-09T13:43:51+02:00</published>
        <updated>2023-05-09T14:02:04+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:07f31362-fa4f-2b9f-4c28-d601f1bfe53a</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-tray-volume/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Gestion de l&#39;icône de volume dans la barre de notifications sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Audio" scheme="http://doc.huc.fr.eu.org/fr/tags/audio/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Petit script pour avoir une icône dans la barre de notifications et
régler le volume sonore. Il est destiné aux environnements minimalistes
comme <a href="http://fluxbox.org/" rel="external">fluxbox</a>, et ne dépend donc de rien en
particulier sauf python et gi.</p>
<p>Il est tout vilain, n&rsquo;hésitez pas à l&rsquo;améliorer ;)</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python3" data-lang="python3"><span style="display:flex;"><span><span style="color:#776e71">#!/usr/local/bin/python3</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">os</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">import</span> <span style="color:#fec418">sys</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">gi</span> <span style="color:#5bc4bf">import</span> require_version
</span></span><span style="display:flex;"><span>require_version(<span style="color:#48b685">&#34;Gtk&#34;</span>, <span style="color:#48b685">&#34;3.0&#34;</span>)
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">from</span> <span style="color:#fec418">gi.repository</span> <span style="color:#5bc4bf">import</span> Gtk, Gdk
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>name<span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;Volume&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">get_lvl</span>():
</span></span><span style="display:flex;"><span>    cmd <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;mixerctl -n outputs.master&#34;</span>
</span></span><span style="display:flex;"><span>    result <span style="color:#5bc4bf">=</span> os<span style="color:#5bc4bf">.</span>popen(cmd)
</span></span><span style="display:flex;"><span>    result <span style="color:#5bc4bf">=</span> result<span style="color:#5bc4bf">.</span>readline()<span style="color:#5bc4bf">.</span>split(<span style="color:#48b685">&#34;,&#34;</span>)[<span style="color:#f99b15">0</span>]
</span></span><span style="display:flex;"><span>    lvl<span style="color:#5bc4bf">=</span> int(int(result)<span style="color:#5bc4bf">/</span><span style="color:#f99b15">255</span><span style="color:#5bc4bf">*</span><span style="color:#f99b15">100</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span> lvl
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">def</span> <span style="color:#06b6ef">get_mute</span>():
</span></span><span style="display:flex;"><span>    cmd <span style="color:#5bc4bf">=</span> <span style="color:#48b685">&#34;mixerctl -n outputs.master.mute&#34;</span>
</span></span><span style="display:flex;"><span>    result <span style="color:#5bc4bf">=</span> os<span style="color:#5bc4bf">.</span>popen(cmd)
</span></span><span style="display:flex;"><span>    result <span style="color:#5bc4bf">=</span> result<span style="color:#5bc4bf">.</span>readline()<span style="color:#5bc4bf">.</span>strip()
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">return</span>(result)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">class</span> <span style="color:#fec418">Menu</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">destroy</span>(self, widget, data<span style="color:#5bc4bf">=</span><span style="color:#815ba4">None</span>):
</span></span><span style="display:flex;"><span>        Gtk<span style="color:#5bc4bf">.</span>main_quit()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">set_icon</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> get_mute() <span style="color:#5bc4bf">==</span> <span style="color:#48b685">&#34;on&#34;</span>:
</span></span><span style="display:flex;"><span>            self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_from_icon_name(<span style="color:#48b685">&#34;stock_volume-mute&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">else</span>:
</span></span><span style="display:flex;"><span>            lvl <span style="color:#5bc4bf">=</span> get_lvl()
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">if</span> lvl <span style="color:#5bc4bf">==</span> <span style="color:#f99b15">0</span>:
</span></span><span style="display:flex;"><span>                self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_from_icon_name(<span style="color:#48b685">&#34;stock_volume-0&#34;</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">elif</span> lvl <span style="color:#5bc4bf">&lt;</span> <span style="color:#f99b15">20</span>:
</span></span><span style="display:flex;"><span>                self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_from_icon_name(<span style="color:#48b685">&#34;stock_volume-min&#34;</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">elif</span> lvl <span style="color:#5bc4bf">&lt;</span> <span style="color:#f99b15">70</span>:
</span></span><span style="display:flex;"><span>                self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_from_icon_name(<span style="color:#48b685">&#34;stock_volume-med&#34;</span>)
</span></span><span style="display:flex;"><span>            <span style="color:#815ba4">elif</span> lvl <span style="color:#5bc4bf">&gt;</span> <span style="color:#f99b15">70</span>:
</span></span><span style="display:flex;"><span>                self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_from_icon_name(<span style="color:#48b685">&#34;stock_volume-max&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">__init__</span>(self):
</span></span><span style="display:flex;"><span>        get_mute()
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>tray <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>StatusIcon()
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>set_icon()
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>connect(<span style="color:#48b685">&#39;popup-menu&#39;</span>, self<span style="color:#5bc4bf">.</span>on_right_click)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>connect(<span style="color:#48b685">&#39;activate&#39;</span>, self<span style="color:#5bc4bf">.</span>on_left_click)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>connect(<span style="color:#48b685">&#39;scroll_event&#39;</span>, self<span style="color:#5bc4bf">.</span>on_scroll)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>tray<span style="color:#5bc4bf">.</span>set_tooltip_text(<span style="color:#48b685">&#39;Volume : </span><span style="color:#f99b15">{}</span><span style="color:#48b685">%&#39;</span><span style="color:#5bc4bf">.</span>format(get_lvl()))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_scroll</span>(self, widget, event):
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">if</span> event<span style="color:#5bc4bf">.</span>direction <span style="color:#5bc4bf">==</span> Gdk<span style="color:#5bc4bf">.</span>ScrollDirection<span style="color:#5bc4bf">.</span>DOWN:
</span></span><span style="display:flex;"><span>            os<span style="color:#5bc4bf">.</span>system(<span style="color:#48b685">&#34;mixerctl outputs.master=-10&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#815ba4">elif</span> event<span style="color:#5bc4bf">.</span>direction <span style="color:#5bc4bf">==</span> Gdk<span style="color:#5bc4bf">.</span>ScrollDirection<span style="color:#5bc4bf">.</span>UP:
</span></span><span style="display:flex;"><span>            os<span style="color:#5bc4bf">.</span>system(<span style="color:#48b685">&#34;mixerctl outputs.master=+10&#34;</span>)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>set_icon()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_left_click</span>(self, event):
</span></span><span style="display:flex;"><span>        os<span style="color:#5bc4bf">.</span>system(<span style="color:#48b685">&#34;mixerctl outputs.master.mute=toggle&#34;</span>)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>set_icon()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">on_right_click</span>(self, icon, button, time):
</span></span><span style="display:flex;"><span>        <span style="color:#776e71"># Quit-menu item</span>
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>menu <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>Menu()
</span></span><span style="display:flex;"><span>        box <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>Box()
</span></span><span style="display:flex;"><span>        box<span style="color:#5bc4bf">.</span>set_spacing(<span style="color:#f99b15">10</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        img <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>Image()
</span></span><span style="display:flex;"><span>        img<span style="color:#5bc4bf">.</span>set_from_stock(Gtk<span style="color:#5bc4bf">.</span>STOCK_CANCEL, Gtk<span style="color:#5bc4bf">.</span>IconSize<span style="color:#5bc4bf">.</span>MENU)
</span></span><span style="display:flex;"><span>        label <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>Label(<span style="color:#48b685">&#34;Quit&#34;</span>)
</span></span><span style="display:flex;"><span>        box<span style="color:#5bc4bf">.</span>add(img)
</span></span><span style="display:flex;"><span>        box<span style="color:#5bc4bf">.</span>add(label)
</span></span><span style="display:flex;"><span>        quit <span style="color:#5bc4bf">=</span> Gtk<span style="color:#5bc4bf">.</span>MenuItem()
</span></span><span style="display:flex;"><span>        quit<span style="color:#5bc4bf">.</span>add(box)
</span></span><span style="display:flex;"><span>        quit<span style="color:#5bc4bf">.</span>connect(<span style="color:#48b685">&#34;activate&#34;</span>, Gtk<span style="color:#5bc4bf">.</span>main_quit)
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>menu<span style="color:#5bc4bf">.</span>append(quit)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>menu<span style="color:#5bc4bf">.</span>show_all()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        self<span style="color:#5bc4bf">.</span>menu<span style="color:#5bc4bf">.</span>popup(<span style="color:#815ba4">None</span>, <span style="color:#815ba4">None</span>, <span style="color:#815ba4">None</span>, self<span style="color:#5bc4bf">.</span>tray, button, time)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#815ba4">def</span> <span style="color:#06b6ef">main</span>(self):
</span></span><span style="display:flex;"><span>        Gtk<span style="color:#5bc4bf">.</span>main()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> <span style="color:#ef6155">__name__</span> <span style="color:#5bc4bf">==</span> <span style="color:#48b685">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span>     app <span style="color:#5bc4bf">=</span> Menu()
</span></span><span style="display:flex;"><span>     app<span style="color:#5bc4bf">.</span>main()
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Une astuce pour gérer le volume audio sous OpenBSD]]></summary>
        <published>2016-12-10T22:01:11+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8246c39b-a86e-dc43-0003-d0995cd3f667</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/dell-alienware-13/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Dell Alienware 13</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Dell" scheme="http://doc.huc.fr.eu.org/fr/tags/dell/" />
        <category term="alienware" scheme="http://doc.huc.fr.eu.org/fr/tags/alienware/" />
        <category term="dmesg" scheme="http://doc.huc.fr.eu.org/fr/tags/dmesg/" />
        <category term="sensors" scheme="http://doc.huc.fr.eu.org/fr/tags/sensors/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Je ne parlerais pas de l&rsquo;installation d&rsquo;OpenBSD en soit. Je fais
fonctionner ce portable sous OpenBSD depuis mes débuts avec la 5.9 !</p>
<p>Cet Alienware AW13 est la première génération.</p>
<div class="row justify-content-center align-items-center">
<figure>
    <a href="/images/openbsd/neofetch-6.6.png" title="Neofetch vue OpenBSD 6.6">
    <picture>
        
        <source srcset="/images/openbsd/neofetch-6.6_hu_d5bd36187dff0862.webp" type="image/webp">
        
        <img alt="Neofetch vue OpenBSD 6.6" height="116" loading="lazy" src="/images/openbsd/neofetch-6.6_hu_27b9b74259cd9613.png" type="image/png" width="250">
    </picture>
    </a>
    <figcaption>Neofetch vue OpenBSD 6.6</figcaption>
</figure>
</div>
<h2 id="ce-qui-fonctionne">Ce qui fonctionne</h2>
<ul>
<li>Intel Audio</li>
<li>Intel CPU - l&rsquo;Hyper-Threading est désactivé par défaut par le système ; 
la virtualisation fonctionne (support VMX/EPT) !</li>
<li>Intel GPU</li>
<li>La carte réseau &ldquo;Attansic Technology E2200&rdquo; <em>AR8035 10/100/1000 PHY, 
rev. 9</em> : firmware 
<a class="man" href="https://man.openbsd.org/alc" title="Page du Manuel OpenBSD pour : alc">alc</a>
 
<ul>
<li><em>depuis OpenBSD 6.6</em></li>
</ul>
</li>
<li>le &ldquo;touchpad&rdquo; - gestion du pointeur : OK ; pas les &ldquo;boutons&rdquo;.</li>
<li>USB EHCI, XHCI (2.x et 3)</li>
<li>Webcam - <em>depuis OpenBSD 6.4</em></li>
</ul>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Pour avoir du réseau, jusqu&rsquo;à OpenBSD 6.6, j&rsquo;étais obligé d&rsquo;utiliser un
adaptateur USB&lt;-&gt;Ethernet… pris en charge par le firmware
<a class="man" href="https://man.openbsd.org/axe" title="Page du Manuel OpenBSD pour : axe">axe</a>
,
reconnu comme &ldquo;ASIX Electronics AX88772&rdquo; rev 2.00/0.01.</div>
<h3 id="modifications-systèmes-nécessaires">Modifications systèmes nécessaires</h3>
<p>Certaines modifications systèmes sont nécessaires.</p>
<h4 id="fichier-etcsysctlconf">Fichier <code>/etc/sysctl.conf </code></h4>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ce problème semble être réglé depuis OpenBSD 6.6 : en effet, une
réinstallation de zéro fonctionne correctement <em>(ce qui n&rsquo;était pas le
cas avec les versions précédentes)</em> !</div>
<p>Sous OpenBSD 6.4 &amp; 6.5, il y a un problème avec l&rsquo;horloge matérielle, ce
qui a pour conséquence que la saisie de caractères se retrouve
démultiplier en session X.</p>
<p>Pour le régler, il faut ajouter au fichier <code>/etc/sysctl.conf</code> : <br>
<code>kern.timecounter.hardware=acpihpet0</code></p>
<h3 id="fichier-etcwsconsctlconf">Fichier <code>/etc/wsconsctl.conf</code></h3>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">display.vblank</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">on</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">mouse.tp.tapping</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">1</span>
</span></span></code></pre></div><ul>
<li>La première option améliore l&rsquo;affichage <code>vblank</code>.</li>
<li>La deuxième améliore la saisie des boutons de souris.</li>
</ul>
<h3 id="fichier-etcx11xorgconf">Fichier <code>/etc/X11/xorg.conf</code></h3>
<p>Il y a un soucis de &ldquo;tearing&rdquo;, problème d&rsquo;accélération graphique avec le
GPU Intel, <abbr title="c'est-à-dire">c-à-d</abbr>
des saccades.</p>
<p>Il est donc nécessaire de créer le fichier <code>/etc/X11/xorg.conf</code> et de le
remplir ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Device&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Identifier  &#34;intel&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Driver  &#34;intel&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Option  &#34;HotPlug&#34;       &#34;true&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">Option  &#34;TearFree&#34;      &#34;true&#34;  #false by default   (avoid tearing)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span></code></pre></div><ul>
<li>C&rsquo;est l&rsquo;option <code>TearFree</code> qui règle le problème.</li>
<li>L&rsquo;option <code>HotPlug</code> prend en charge les périphériques qui se montent à 
chaud…</li>
</ul>
<h2 id="ce-qui-ne-fonctionne-pas">Ce qui ne fonctionne pas</h2>
<ul>
<li>Le Bluetooth - le support a été supprimé dans OpenBSD pour des raisons 
de sécurité depuis longtemps</li>
<li>La puce Wifi, une &ldquo;Atheros&rdquo; : vendor &ldquo;Atheros&rdquo;, unknown product 0x003e 
(class network subclass miscellaneous, rev 0x20)</li>
<li>Nvidia GPU, technologie Optimus - ne sera jamais pris en charge, tant 
que ladite société ne libérera pas les sources.</li>
</ul>
<h2 id="dmesg">dmesg</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>OpenBSD 6.6 <span style="color:#5bc4bf">(</span>GENERIC.MP<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#372: Sat Oct 12 10:56:27 MDT 2019</span>
</span></span><span style="display:flex;"><span>    deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">8487260160</span> <span style="color:#5bc4bf">(</span>8094MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">8217325568</span> <span style="color:#5bc4bf">(</span>7836MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>mpath0 at root
</span></span><span style="display:flex;"><span>scsibus0 at mpath0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>mainbus0 at root
</span></span><span style="display:flex;"><span>bios0 at mainbus0: SMBIOS rev. 2.8 @ 0xec580 <span style="color:#5bc4bf">(</span><span style="color:#f99b15">74</span> entries<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>bios0: vendor Alienware version <span style="color:#48b685">&#34;A08&#34;</span> date 01/25/2018
</span></span><span style="display:flex;"><span>bios0: Alienware Alienware <span style="color:#f99b15">13</span>
</span></span><span style="display:flex;"><span>acpi0 at bios0: ACPI 5.0
</span></span><span style="display:flex;"><span>acpi0: sleep states S0 S3 S4 S5
</span></span><span style="display:flex;"><span>acpi0: tables DSDT FACP APIC FPDT FIDT MCFG HPET SSDT UEFI SSDT ASF! SLIC SSDT SSDT SSDT SSDT CSRT SSDT
</span></span><span style="display:flex;"><span>acpi0: wakeup devices PEG0<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEGP<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEG1<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEGP<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEG2<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEGP<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> RP01<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PXSX<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> RP02<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PXSX<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> RP03<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PXSX<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> RP04<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PXSX<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> RP05<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> PEGP<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">[</span>...<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>acpitimer0 at acpi0: <span style="color:#f99b15">3579545</span> Hz, <span style="color:#f99b15">24</span> bits
</span></span><span style="display:flex;"><span>acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
</span></span><span style="display:flex;"><span>cpu0 at mainbus0: apid <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>boot processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu0: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> i5-4210U CPU @ 1.70GHz, 799.46 MHz, 06-45-01
</span></span><span style="display:flex;"><span>cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu0: 256KB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu0: smt 0, core 0, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>mtrr: Pentium Pro MTRR support, <span style="color:#f99b15">10</span> var ranges, <span style="color:#f99b15">88</span> fixed ranges
</span></span><span style="display:flex;"><span>cpu0: apic clock running at 99MHz
</span></span><span style="display:flex;"><span>cpu0: mwait <span style="color:#ef6155">min</span><span style="color:#5bc4bf">=</span>64, <span style="color:#ef6155">max</span><span style="color:#5bc4bf">=</span>64, C-substates<span style="color:#5bc4bf">=</span>0.2.1.2.4.1.1.1, IBE
</span></span><span style="display:flex;"><span>cpu1 at mainbus0: apid <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu1: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> i5-4210U CPU @ 1.70GHz, 799.32 MHz, 06-45-01
</span></span><span style="display:flex;"><span>cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu1: 256KB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu1: smt 0, core 1, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>cpu2 at mainbus0: apid <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu2: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> i5-4210U CPU @ 1.70GHz, 799.31 MHz, 06-45-01
</span></span><span style="display:flex;"><span>cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu2: 256KB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu2: smt 1, core 0, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>cpu3 at mainbus0: apid <span style="color:#f99b15">3</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu3: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span> i5-4210U CPU @ 1.70GHz, 799.31 MHz, 06-45-01
</span></span><span style="display:flex;"><span>cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
</span></span><span style="display:flex;"><span>cpu3: 256KB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu3: smt 1, core 1, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>ioapic0 at mainbus0: apid <span style="color:#f99b15">2</span> pa 0xfec00000, version 20, <span style="color:#f99b15">40</span> pins
</span></span><span style="display:flex;"><span>acpimadt0: bogus nmi <span style="color:#815ba4">for</span> apid <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>acpimadt0: bogus nmi <span style="color:#815ba4">for</span> apid <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>acpimadt0: bogus nmi <span style="color:#815ba4">for</span> apid <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>acpimadt0: bogus nmi <span style="color:#815ba4">for</span> apid <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>acpimcfg0 at acpi0
</span></span><span style="display:flex;"><span>acpimcfg0: addr 0xf8000000, bus 0-63
</span></span><span style="display:flex;"><span>acpihpet0 at acpi0: <span style="color:#f99b15">14318179</span> Hz
</span></span><span style="display:flex;"><span>acpiprt0 at acpi0: bus <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>PCI0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt1 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>PEG0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt2 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>PEG1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt3 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>PEG2<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt4 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP01<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt5 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP02<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt6 at acpi0: bus <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">(</span>RP03<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt7 at acpi0: bus <span style="color:#f99b15">2</span> <span style="color:#5bc4bf">(</span>RP04<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt8 at acpi0: bus <span style="color:#f99b15">3</span> <span style="color:#5bc4bf">(</span>RP05<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt9 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP06<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt10 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP07<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt11 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP08<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiec0 at acpi0: not present
</span></span><span style="display:flex;"><span>acpiec1 at acpi0
</span></span><span style="display:flex;"><span>acpicpu0 at acpi0: C2<span style="color:#5bc4bf">(</span>200@148 mwait.1@0x33<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpicpu1 at acpi0: C2<span style="color:#5bc4bf">(</span>200@148 mwait.1@0x33<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpicpu2 at acpi0: C2<span style="color:#5bc4bf">(</span>200@148 mwait.1@0x33<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpicpu3 at acpi0: C2<span style="color:#5bc4bf">(</span>200@148 mwait.1@0x33<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpipwrres0 at acpi0: PG00, resource <span style="color:#815ba4">for</span> PEG0
</span></span><span style="display:flex;"><span>acpipwrres1 at acpi0: PG01, resource <span style="color:#815ba4">for</span> PEG1
</span></span><span style="display:flex;"><span>acpipwrres2 at acpi0: PG02, resource <span style="color:#815ba4">for</span> PEG2
</span></span><span style="display:flex;"><span>acpipwrres3 at acpi0: PC05, resource <span style="color:#815ba4">for</span> RP05
</span></span><span style="display:flex;"><span>acpitz0 at acpi0: critical temperature is <span style="color:#f99b15">105</span> degC
</span></span><span style="display:flex;"><span>acpitz1 at acpi0: critical temperature is <span style="color:#f99b15">105</span> degC
</span></span><span style="display:flex;"><span>acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
</span></span><span style="display:flex;"><span>acpicmos0 at acpi0
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3403&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpibat0 at acpi0: BAT1 model <span style="color:#48b685">&#34;PABAS0241231&#34;</span> serial 0x75d1 type Li-Ion oem <span style="color:#48b685">&#34;TOSHIBA&#34;</span>
</span></span><span style="display:flex;"><span>acpiac0 at acpi0: AC unit online
</span></span><span style="display:flex;"><span>acpibtn0 at acpi0: LID0
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT33C7&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INTL9C60&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>dwiic0 at acpi0 I2C1 addr 0xfe105000/0x1000 irq <span style="color:#f99b15">7</span>
</span></span><span style="display:flex;"><span>iic0 at dwiic0
</span></span><span style="display:flex;"><span>ihidev0 at iic0 addr 0x2cdwiic0: timed out reading remaining <span style="color:#f99b15">29</span>
</span></span><span style="display:flex;"><span>, failed fetching initial HID descriptor
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;SMO8810&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3402&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C14&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpibtn1 at acpi0: PWRB
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C14&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;DELLABCE&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C32&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C32&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C32&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;CPL0002&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;INT3400&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpivideo0 at acpi0: GFX0
</span></span><span style="display:flex;"><span>acpivout0 at acpivideo0: DD1F
</span></span><span style="display:flex;"><span>cpu0: using VERW MDS workaround <span style="color:#5bc4bf">(</span>except on vmm entry<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>pci0 at mainbus0 bus <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pchb0 at pci0 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Core 4G Host&#34;</span> rev 0x0b
</span></span><span style="display:flex;"><span>inteldrm0 at pci0 dev <span style="color:#f99b15">2</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel HD Graphics&#34;</span> rev 0x0b
</span></span><span style="display:flex;"><span>drm0 at inteldrm0
</span></span><span style="display:flex;"><span>inteldrm0: msi
</span></span><span style="display:flex;"><span>azalia0 at pci0 dev <span style="color:#f99b15">3</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Core 4G HD Audio&#34;</span> rev 0x0b: msi
</span></span><span style="display:flex;"><span>azalia0: No codecs found
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Intel Core 4G Thermal&#34;</span> rev 0x0b at pci0 dev <span style="color:#f99b15">4</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>xhci0 at pci0 dev <span style="color:#f99b15">20</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 8 Series xHCI&#34;</span> rev 0x04: msi, xHCI 1.0
</span></span><span style="display:flex;"><span>usb0 at xhci0: USB revision 3.0
</span></span><span style="display:flex;"><span>uhub0 at usb0 configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel xHCI root hub&#34;</span> rev 3.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Intel 8 Series MEI&#34;</span> rev 0x04 at pci0 dev <span style="color:#f99b15">22</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>azalia1 at pci0 dev <span style="color:#f99b15">27</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 8 Series HD Audio&#34;</span> rev 0x04: msi
</span></span><span style="display:flex;"><span>azalia1: codecs: Realtek/0x0255
</span></span><span style="display:flex;"><span>audio0 at azalia1
</span></span><span style="display:flex;"><span>ppb0 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 8 Series PCIE&#34;</span> rev 0xe4: msi
</span></span><span style="display:flex;"><span>pci1 at ppb0 bus <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>vendor <span style="color:#48b685">&#34;Atheros&#34;</span>, unknown product 0x003e <span style="color:#5bc4bf">(</span>class network subclass miscellaneous, rev 0x20<span style="color:#5bc4bf">)</span> at pci1 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>ppb1 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">3</span> <span style="color:#48b685">&#34;Intel 8 Series PCIE&#34;</span> rev 0xe4: msi
</span></span><span style="display:flex;"><span>pci2 at ppb1 bus <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>alc0 at pci2 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Attansic Technology E2200&#34;</span> rev 0x10: msi, address 34:e6:d7:1b:7f:14
</span></span><span style="display:flex;"><span>atphy0 at alc0 phy 0: AR8035 10/100/1000 PHY, rev. <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>ppb2 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">4</span> <span style="color:#48b685">&#34;Intel 8 Series PCIE&#34;</span> rev 0xe4: msi
</span></span><span style="display:flex;"><span>pci3 at ppb2 bus <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>vendor <span style="color:#48b685">&#34;NVIDIA&#34;</span>, unknown product 0x1392 <span style="color:#5bc4bf">(</span>class display subclass 3D, rev 0xa2<span style="color:#5bc4bf">)</span> at pci3 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>ehci0 at pci0 dev <span style="color:#f99b15">29</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 8 Series USB&#34;</span> rev 0x04: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">23</span>
</span></span><span style="display:flex;"><span>usb1 at ehci0: USB revision 2.0
</span></span><span style="display:flex;"><span>uhub1 at usb1 configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel EHCI root hub&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>pcib0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 8 Series LPC&#34;</span> rev 0x04
</span></span><span style="display:flex;"><span>ahci0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">2</span> <span style="color:#48b685">&#34;Intel 8 Series AHCI&#34;</span> rev 0x04: msi, AHCI 1.3
</span></span><span style="display:flex;"><span>ahci0: port 0: 6.0Gb/s
</span></span><span style="display:flex;"><span>scsibus1 at ahci0: <span style="color:#f99b15">32</span> targets
</span></span><span style="display:flex;"><span>sd0 at scsibus1 targ <span style="color:#f99b15">0</span> lun 0: &lt;ATA, ST500LT012-1DG14, 0001&gt; naa.5000c5009d2436d7
</span></span><span style="display:flex;"><span>sd0: 476940MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">976773168</span> sectors
</span></span><span style="display:flex;"><span>ichiic0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">3</span> <span style="color:#48b685">&#34;Intel 8 Series SMBus&#34;</span> rev 0x04: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">18</span>
</span></span><span style="display:flex;"><span>iic1 at ichiic0
</span></span><span style="display:flex;"><span>iic1: addr 0x29 <span style="color:#ef6155">07</span><span style="color:#5bc4bf">=</span>ff <span style="color:#ef6155">0f</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">33</span> <span style="color:#ef6155">10</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">08</span> <span style="color:#ef6155">11</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">05</span> <span style="color:#ef6155">12</span><span style="color:#5bc4bf">=</span>8f <span style="color:#ef6155">13</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">54</span> <span style="color:#ef6155">14</span><span style="color:#5bc4bf">=</span>a0 <span style="color:#ef6155">15</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">31</span> <span style="color:#ef6155">16</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">28</span> <span style="color:#ef6155">17</span><span style="color:#5bc4bf">=</span>1f <span style="color:#ef6155">18</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span> <span style="color:#ef6155">19</span><span style="color:#5bc4bf">=</span>b9 <span style="color:#ef6155">1a</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">60</span> <span style="color:#ef6155">1b</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">65</span> <span style="color:#ef6155">1c</span><span style="color:#5bc4bf">=</span>c0 <span style="color:#ef6155">1e</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">20</span> <span style="color:#ef6155">20</span><span style="color:#5bc4bf">=</span>7f <span style="color:#ef6155">22</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">40</span> <span style="color:#ef6155">25</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">40</span> <span style="color:#ef6155">27</span><span style="color:#5bc4bf">=</span>ff <span style="color:#ef6155">29</span><span style="color:#5bc4bf">=</span>f3 <span style="color:#ef6155">2b</span><span style="color:#5bc4bf">=</span>ff <span style="color:#ef6155">2d</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">45</span> <span style="color:#ef6155">2f</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">20</span> <span style="color:#ef6155">30</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">95</span> <span style="color:#ef6155">31</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">26</span> <span style="color:#ef6155">32</span><span style="color:#5bc4bf">=</span>0e <span style="color:#ef6155">33</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">10</span> <span style="color:#ef6155">87</span><span style="color:#5bc4bf">=</span>ff <span style="color:#ef6155">8f</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">33</span> <span style="color:#ef6155">90</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">08</span> <span style="color:#ef6155">91</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">05</span> <span style="color:#ef6155">92</span><span style="color:#5bc4bf">=</span>8f <span style="color:#ef6155">93</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">54</span> <span style="color:#ef6155">94</span><span style="color:#5bc4bf">=</span>a0 <span style="color:#ef6155">95</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">31</span> <span style="color:#ef6155">96</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">28</span> <span style="color:#ef6155">97</span><span style="color:#5bc4bf">=</span>1f <span style="color:#ef6155">98</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">22</span> <span style="color:#ef6155">99</span><span style="color:#5bc4bf">=</span>b9 <span style="color:#ef6155">9a</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">60</span> <span style="color:#ef6155">9b</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">65</span> <span style="color:#ef6155">9c</span><span style="color:#5bc4bf">=</span>c0 <span style="color:#ef6155">9e</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">20</span> <span style="color:#ef6155">a0</span><span style="color:#5bc4bf">=</span>7f <span style="color:#ef6155">a2</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">40</span> <span style="color:#ef6155">a5</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">40</span> <span style="color:#ef6155">a7</span><span style="color:#5bc4bf">=</span>df <span style="color:#ef6155">a9</span><span style="color:#5bc4bf">=</span>f1 <span style="color:#ef6155">ab</span><span style="color:#5bc4bf">=</span>fc <span style="color:#ef6155">ad</span><span style="color:#5bc4bf">=</span>3e <span style="color:#ef6155">af</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">20</span> <span style="color:#ef6155">b0</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">95</span> <span style="color:#ef6155">b1</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">25</span> <span style="color:#ef6155">b2</span><span style="color:#5bc4bf">=</span>0e <span style="color:#ef6155">b3</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">10</span> words <span style="color:#ef6155">00</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">01</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">02</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">03</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">04</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">05</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">06</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0000</span> <span style="color:#ef6155">07</span><span style="color:#5bc4bf">=</span>ffff
</span></span><span style="display:flex;"><span>spdmem0 at iic1 addr 0x50: 4GB DDR3 SDRAM PC3-12800 SO-DIMM
</span></span><span style="display:flex;"><span>spdmem1 at iic1 addr 0x52: 4GB DDR3 SDRAM PC3-12800 SO-DIMM
</span></span><span style="display:flex;"><span>isa0 at pcib0
</span></span><span style="display:flex;"><span>isadma0 at isa0
</span></span><span style="display:flex;"><span>pckbc0 at isa0 port 0x60/5 irq <span style="color:#f99b15">1</span> irq <span style="color:#f99b15">12</span>
</span></span><span style="display:flex;"><span>pckbd0 at pckbc0 <span style="color:#5bc4bf">(</span>kbd slot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wskbd0 at pckbd0: console keyboard
</span></span><span style="display:flex;"><span>pms0 at pckbc0 <span style="color:#5bc4bf">(</span>aux slot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wsmouse0 at pms0 mux <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pms0: Synaptics clickpad, firmware 8.1, 0x1e2b1 0x840300
</span></span><span style="display:flex;"><span>pcppi0 at isa0 port 0x61
</span></span><span style="display:flex;"><span>spkr0 at pcppi0
</span></span><span style="display:flex;"><span>vmm0 at mainbus0: VMX/EPT
</span></span><span style="display:flex;"><span>uhidev0 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;E-Signal USB Gaming Mouse&#34;</span> rev 2.00/1.42 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uhidev0: iclass 3/1
</span></span><span style="display:flex;"><span>ums0 at uhidev0: <span style="color:#f99b15">5</span> buttons, Z and W dir
</span></span><span style="display:flex;"><span>wsmouse1 at ums0 mux <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhidev1 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;E-Signal USB Gaming Mouse&#34;</span> rev 2.00/1.42 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uhidev1: iclass 3/0, <span style="color:#f99b15">6</span> report ids
</span></span><span style="display:flex;"><span>ukbd0 at uhidev1 reportid 1: <span style="color:#f99b15">8</span> variable keys, <span style="color:#f99b15">6</span> key codes
</span></span><span style="display:flex;"><span>wskbd1 at ukbd0 mux <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>uhid0 at uhidev1 reportid 2: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>1, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhid1 at uhidev1 reportid 3: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>2, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhid2 at uhidev1 reportid 6: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>3, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhidev2 at uhub0 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">2</span> <span style="color:#48b685">&#34;E-Signal USB Gaming Mouse&#34;</span> rev 2.00/1.42 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>uhidev2: iclass 3/0
</span></span><span style="display:flex;"><span>uhid3 at uhidev2: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>32, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>32, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">8</span>
</span></span><span style="display:flex;"><span>uvideo0 at uhub0 port <span style="color:#f99b15">6</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;CN036P597248751HABEMA00 Integrated_Webcam_FHD&#34;</span> rev 2.00/47.18 addr <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span>video0 at uvideo0
</span></span><span style="display:flex;"><span>uhidev3 at uhub0 port <span style="color:#f99b15">7</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Alienware AW13&#34;</span> rev 0.02/0.00 addr <span style="color:#f99b15">4</span>
</span></span><span style="display:flex;"><span>uhidev3: iclass 3/0, <span style="color:#f99b15">2</span> report ids
</span></span><span style="display:flex;"><span>uhid4 at uhidev3 reportid 1: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>8, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhid5 at uhidev3 reportid 2: <span style="color:#ef6155">input</span><span style="color:#5bc4bf">=</span>0, <span style="color:#ef6155">output</span><span style="color:#5bc4bf">=</span>8, <span style="color:#ef6155">feature</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhub2 at uhub1 port <span style="color:#f99b15">1</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel Rate Matching Hub&#34;</span> rev 2.00/0.04 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>vscsi0 at root
</span></span><span style="display:flex;"><span>scsibus2 at vscsi0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>softraid0 at root
</span></span><span style="display:flex;"><span>scsibus3 at softraid0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>root on sd0a <span style="color:#5bc4bf">(</span>25417e6d803941c6.a<span style="color:#5bc4bf">)</span> swap on sd0b dump on sd0b
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>drm<span style="color:#5bc4bf">]</span> ACPI BIOS requests an excessive sleep of <span style="color:#f99b15">2000</span> ms, using <span style="color:#f99b15">1500</span> ms instead
</span></span><span style="display:flex;"><span>inteldrm0: 1920x1080, 32bpp
</span></span><span style="display:flex;"><span>wsdisplay0 at inteldrm0 mux 1: console <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>, using wskbd0
</span></span><span style="display:flex;"><span>wskbd1: connecting to wsdisplay0
</span></span><span style="display:flex;"><span>wsdisplay0: screen 1-5 added <span style="color:#5bc4bf">(</span>std, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h2 id="hwsensors">hw.sensors</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ sysctl hw.sensors
</span></span><span style="display:flex;"><span>hw.sensors.cpu0.temp0<span style="color:#5bc4bf">=</span>48.00 degC
</span></span><span style="display:flex;"><span>hw.sensors.acpitz0.temp0<span style="color:#5bc4bf">=</span>27.80 degC <span style="color:#5bc4bf">(</span>zone temperature<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpitz1.temp0<span style="color:#5bc4bf">=</span>29.80 degC <span style="color:#5bc4bf">(</span>zone temperature<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.volt0<span style="color:#5bc4bf">=</span>14.80 VDC <span style="color:#5bc4bf">(</span>voltage<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.volt1<span style="color:#5bc4bf">=</span>17.02 VDC <span style="color:#5bc4bf">(</span>current voltage<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.current0<span style="color:#5bc4bf">=</span>65.53 A <span style="color:#5bc4bf">(</span>rate<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.amphour0<span style="color:#5bc4bf">=</span>3.06 Ah <span style="color:#5bc4bf">(</span>last full capacity<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.amphour1<span style="color:#5bc4bf">=</span>0.30 Ah <span style="color:#5bc4bf">(</span>warning capacity<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.amphour2<span style="color:#5bc4bf">=</span>0.09 Ah <span style="color:#5bc4bf">(</span>low capacity<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.amphour3<span style="color:#5bc4bf">=</span>3.06 Ah <span style="color:#5bc4bf">(</span>remaining capacity<span style="color:#5bc4bf">)</span>, OK
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.amphour4<span style="color:#5bc4bf">=</span>3.54 Ah <span style="color:#5bc4bf">(</span>design capacity<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.raw0<span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>battery full<span style="color:#5bc4bf">)</span>, OK
</span></span><span style="display:flex;"><span>hw.sensors.acpibat0.raw1<span style="color:#5bc4bf">=</span><span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>discharge cycles<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpiac0.indicator0<span style="color:#5bc4bf">=</span>On <span style="color:#5bc4bf">(</span>power supply<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibtn0.indicator0<span style="color:#5bc4bf">=</span>On <span style="color:#5bc4bf">(</span>lid open<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Récapitulatif de ce qui fonctionne ou pas sur un Dell Alienware AW13 de première génération sous OpenBSD]]></summary>
        <published>2016-12-10T20:14:07+01:00</published>
        <updated>2025-10-06T11:59:02+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:52620872-78cd-9da5-fe41-2f38cbf81219</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/epson-bx525wd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Epson Stylus Office BX525WD / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Epson" scheme="http://doc.huc.fr.eu.org/fr/tags/epson/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Testée sur OpenBSD stable : 6.0 ⇒ 6.6 !</p>
<h2 id="gestion-de-limpression">Gestion de l&rsquo;impression</h2>
<p>La partie impression fonctionne très bien…</p>
<p>Indiquez à Cups d&rsquo;installer le fichier ppd relatif à la version BX525WD
ou BX535WD.</p>
<p>Si vous avez <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

le paquet <strong>gutenprint</strong>, vous aurez le choix entre sa version et celle
de <strong>foomatic</strong>.</p>
<p><strong>Choisissez le protocole <code>lpd</code></strong>, c&rsquo;est celui qui fonctionne le mieux…</p>
<p>Tel que : <code>lpd://adr_ip/PASSTHRU</code></p>
<p>Si <a class="inside" href="/fr/sys/openbsd/avahi/" title="Lien interne vers l&#39;article : 'Avahi (Découverte de services multicast DNS)'">Avahi</a>
 est installé, elle
est vu par le biais du protocole DNS-SD, voire mDNS, elle s&rsquo;installe,
mais après lors d&rsquo;impression, cups n&rsquo;arrive pas à discuter avec…</p>
<hr>
<p>Pensez à <a class="inside" href="/fr/sys/openbsd/rcctl/#red%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">redémarrer</a>

le service <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>
 !</p>
<h2 id="gestion-du-scanner">Gestion du scanner</h2>
<p>Après avoir <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

les paquets : <code>sane-backends xsane</code>, il vous faudra :</p>
<ul>
<li>modifier le fichier <code>/etc/sane.d/dll.conf</code> pour ajouter : <strong>epkowa</strong>.</li>
<li>il vous faudra ajouter le fichier de configuration
<code>/etc/sane.d/epkowa.conf</code>, et modifiez-le :
<ul>
<li>si vous êtes connecté en usb : &lsquo;usb 0x04b8 0xProductId&rsquo;</li>
<li>ou si vous l&rsquo;avez en réseau : &rsquo;net adr_ip 1865'</li>
</ul>
</li>
</ul>
<p>Une fois modifié, vous pourrez exécuter <code>xsane</code>.</p>
<hr>
<p>Exemple du fichier <code>epkowa.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># epkowa.conf -- sample configuration for the EPKOWA SANE backend</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Copyright (C) 2004, 2008, 2009  Olaf Meeuwissen</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># See sane-epkowa(5), sane-usb(5) and sane-scsi(5) for details.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Detect all devices supported by the backend.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># If you don&#39;t have a SCSI device, you can comment out the &#34;scsi&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># keyword.  Similarly for the other keywords.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">usb</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">scsi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For any USB scanner not known to the backend (yet), you may, at your</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># own peril(!!), force the backend to recognise and use it via libusb.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># You can do so by the following configuration command:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># </span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   usb &lt;USB vendor ID&gt; &lt;USB product ID&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># SEIKO EPSON&#39;s USB vendor ID is &#39;0x04b8&#39; (without quotes).  In order</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># to find the USB product ID, use lsusb(1).</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># A sample configuration for the Epson Perfection 1650 (Epson GT-8200),</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># which has a product ID of 0x0110, would look as follows:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#usb 0x04b8 0x0110</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For SCSI devices not detected, you can add an entry like:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   scsi EPSON GT-20000</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># where the GT-20000 bit corresponds to the SCSI model information as</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># shown in the output of dmesg(1) or in the /var/log/kern.log file.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Network attached devices may be made to work by first installing the</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># (non-free) iscan-network-nt package and then adding configuration lines</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># as per information below.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># For each network attached device, you must add an entry as follows:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   net &lt;IP-address|hostname&gt; [port-number]</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Ask your network administrator for the device&#39;s IP address or check</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># for yourself on the panel (if it has one).  The port-number is very</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># optional and defaults to 1865.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Note that network attached devices are not queried unless configured</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># in this file.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Examples:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net 192.16.136.2 1865</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net 10.0.0.1</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#net scanner.mydomain.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Some backend behaviour can be customized by using the option keyword</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># followed by an option name, as shown below.</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#   option &lt;option-name&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Currently available options:</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Makes the automatic document feeder the default document source</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#option prefer-adf</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Support de l&#39;imprimante MFP, de marque Epson, modèle Stylus Office BX5S5WD, sous OpenBSD]]></summary>
        <published>2016-12-10T20:47:36+02:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:b9c87623-8fd9-a4ec-fccf-8895931327c9</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/dell-xps-m1330/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Dell XPS M1330</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Dell" scheme="http://doc.huc.fr.eu.org/fr/tags/dell/" />
        <category term="alienware" scheme="http://doc.huc.fr.eu.org/fr/tags/alienware/" />
        <category term="dmesg" scheme="http://doc.huc.fr.eu.org/fr/tags/dmesg/" />
        <category term="sensors" scheme="http://doc.huc.fr.eu.org/fr/tags/sensors/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Un petit apercu du support du Dell XPS M1330 sous OpenBSD</p>
<h2 id="ce-qui-fonctionne">Ce qui fonctionne</h2>
<ul>
<li>le GPU Nvidia</li>
<li>la carte réseau Broadcom, reconnue comme bge</li>
<li>le son</li>
<li>le lecteur biométrique - reconnu !</li>
</ul>
<h2 id="ce-qui-ne-fonctionne-pas">Ce qui ne fonctionne pas</h2>
<ul>
<li>le lecteur de cartes mémoires intégré</li>
</ul>
<h2 id="dmesg">dmesg</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>OpenBSD 6.0 <span style="color:#5bc4bf">(</span>GENERIC.MP<span style="color:#5bc4bf">)</span> <span style="color:#776e71">#2319: Tue Jul 26 13:00:43 MDT 2016</span>
</span></span><span style="display:flex;"><span>    deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
</span></span><span style="display:flex;"><span>real <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4276531200</span> <span style="color:#5bc4bf">(</span>4078MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>avail <span style="color:#ef6155">mem</span> <span style="color:#5bc4bf">=</span> <span style="color:#f99b15">4142448640</span> <span style="color:#5bc4bf">(</span>3950MB<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>mpath0 at root
</span></span><span style="display:flex;"><span>scsibus0 at mpath0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>mainbus0 at root
</span></span><span style="display:flex;"><span>bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf71d0 <span style="color:#5bc4bf">(</span><span style="color:#f99b15">44</span> entries<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>bios0: vendor Dell Inc. version <span style="color:#48b685">&#34;A15&#34;</span> date 12/26/2008
</span></span><span style="display:flex;"><span>bios0: Dell Inc. XPS M1330
</span></span><span style="display:flex;"><span>acpi0 at bios0: rev <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>acpi0: sleep states S0 S3 S4 S5
</span></span><span style="display:flex;"><span>acpi0: tables DSDT FACP HPET APIC MCFG SLIC BOOT SSDT
</span></span><span style="display:flex;"><span>acpi0: wakeup devices PCI0<span style="color:#5bc4bf">(</span>S5<span style="color:#5bc4bf">)</span> PCIE<span style="color:#5bc4bf">(</span>S4<span style="color:#5bc4bf">)</span> USB1<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> USB2<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> USB3<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> USB4<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> USB5<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> EHC2<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> EHCI<span style="color:#5bc4bf">(</span>S0<span style="color:#5bc4bf">)</span> AZAL<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP01<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP02<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP03<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP04<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP05<span style="color:#5bc4bf">(</span>S3<span style="color:#5bc4bf">)</span> RP06<span style="color:#5bc4bf">(</span>S5<span style="color:#5bc4bf">)</span> <span style="color:#5bc4bf">[</span>...<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>acpitimer0 at acpi0: <span style="color:#f99b15">3579545</span> Hz, <span style="color:#f99b15">24</span> bits
</span></span><span style="display:flex;"><span>acpihpet0 at acpi0: <span style="color:#f99b15">14318179</span> Hz
</span></span><span style="display:flex;"><span>acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
</span></span><span style="display:flex;"><span>cpu0 at mainbus0: apid <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>boot processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu0: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span><span style="color:#f99b15">2</span> Duo CPU T5800 @ 2.00GHz, 965.53 MHz
</span></span><span style="display:flex;"><span>cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,EST,TM2,SSSE3,CX16,xTPR,PDCM,NXE,LONG,LAHF,PERF,SENSOR
</span></span><span style="display:flex;"><span>cpu0: 2MB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu0: smt 0, core 0, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>mtrr: Pentium Pro MTRR support, <span style="color:#f99b15">8</span> var ranges, <span style="color:#f99b15">88</span> fixed ranges
</span></span><span style="display:flex;"><span>cpu0: apic clock running at 199MHz
</span></span><span style="display:flex;"><span>cpu0: mwait <span style="color:#ef6155">min</span><span style="color:#5bc4bf">=</span>64, <span style="color:#ef6155">max</span><span style="color:#5bc4bf">=</span>64, C-substates<span style="color:#5bc4bf">=</span>0.2.2.2.2, IBE
</span></span><span style="display:flex;"><span>cpu1 at mainbus0: apid <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">(</span>application processor<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>cpu1: Intel<span style="color:#5bc4bf">(</span>R<span style="color:#5bc4bf">)</span> Core<span style="color:#5bc4bf">(</span>TM<span style="color:#5bc4bf">)</span><span style="color:#f99b15">2</span> Duo CPU T5800 @ 2.00GHz, 927.61 MHz
</span></span><span style="display:flex;"><span>cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,DTES64,MWAIT,DS-CPL,EST,TM2,SSSE3,CX16,xTPR,PDCM,NXE,LONG,LAHF,PERF,SENSOR
</span></span><span style="display:flex;"><span>cpu1: 2MB 64b/line 8-way L2 cache
</span></span><span style="display:flex;"><span>cpu1: smt 0, core 1, package <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>ioapic0 at mainbus0: apid <span style="color:#f99b15">2</span> pa 0xfec00000, version 20, <span style="color:#f99b15">24</span> pins
</span></span><span style="display:flex;"><span>acpimcfg0 at acpi0 addr 0xf8000000, bus 0-63
</span></span><span style="display:flex;"><span>acpiprt0 at acpi0: bus <span style="color:#f99b15">3</span> <span style="color:#5bc4bf">(</span>PCIE<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt1 at acpi0: bus <span style="color:#f99b15">1</span> <span style="color:#5bc4bf">(</span>AGP_<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt2 at acpi0: bus <span style="color:#f99b15">11</span> <span style="color:#5bc4bf">(</span>RP01<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt3 at acpi0: bus <span style="color:#f99b15">12</span> <span style="color:#5bc4bf">(</span>RP02<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt4 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP03<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt5 at acpi0: bus <span style="color:#f99b15">13</span> <span style="color:#5bc4bf">(</span>RP04<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt6 at acpi0: bus -1 <span style="color:#5bc4bf">(</span>RP05<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt7 at acpi0: bus <span style="color:#f99b15">9</span> <span style="color:#5bc4bf">(</span>RP06<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpiprt8 at acpi0: bus <span style="color:#f99b15">0</span> <span style="color:#5bc4bf">(</span>PCI0<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>acpicpu0 at acpi0: !C3<span style="color:#5bc4bf">(</span>100@57 mwait.3@0x30<span style="color:#5bc4bf">)</span>, !C2<span style="color:#5bc4bf">(</span>500@1 mwait.1@0x10<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpicpu1 at acpi0: !C3<span style="color:#5bc4bf">(</span>100@57 mwait.3@0x30<span style="color:#5bc4bf">)</span>, !C2<span style="color:#5bc4bf">(</span>500@1 mwait.1@0x10<span style="color:#5bc4bf">)</span>, C1<span style="color:#5bc4bf">(</span>1000@1 mwait.1<span style="color:#5bc4bf">)</span>, PSS
</span></span><span style="display:flex;"><span>acpitz0 at acpi0: critical temperature is <span style="color:#f99b15">87</span> degC
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0F13&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0303&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpibtn0 at acpi0: LID_
</span></span><span style="display:flex;"><span>acpibtn1 at acpi0: PBTN
</span></span><span style="display:flex;"><span>acpibtn2 at acpi0: SBTN
</span></span><span style="display:flex;"><span>acpiac0 at acpi0: AC unit online
</span></span><span style="display:flex;"><span>acpibat0 at acpi0: BAT0 not present
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;PNP0C32&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;*pnp0c14&#34;</span> at acpi0 not configured
</span></span><span style="display:flex;"><span>acpivideo0 at acpi0: VID_
</span></span><span style="display:flex;"><span>acpivout0 at acpivideo0: LCD_
</span></span><span style="display:flex;"><span>acpivideo1 at acpi0: VID_
</span></span><span style="display:flex;"><span>acpivout at acpivideo1 not configured
</span></span><span style="display:flex;"><span>acpivideo2 at acpi0: VID2
</span></span><span style="display:flex;"><span>cpu0: Enhanced SpeedStep <span style="color:#f99b15">965</span> MHz: speeds: 2000, 1600, 1200, <span style="color:#f99b15">800</span> MHz
</span></span><span style="display:flex;"><span>pci0 at mainbus0 bus <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pchb0 at pci0 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel GM965 Host&#34;</span> rev 0x0c
</span></span><span style="display:flex;"><span>ppb0 at pci0 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel GM965 PCIE&#34;</span> rev 0x0c: msi
</span></span><span style="display:flex;"><span>pci1 at ppb0 bus <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>vga1 at pci1 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;NVIDIA GeForce 8400M GS&#34;</span> rev 0xa1
</span></span><span style="display:flex;"><span>wsdisplay0 at vga1 mux 1: console <span style="color:#5bc4bf">(</span>80x25, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wsdisplay0: screen 1-5 added <span style="color:#5bc4bf">(</span>80x25, vt100 emulation<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>uhci0 at pci0 dev <span style="color:#f99b15">26</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">20</span>
</span></span><span style="display:flex;"><span>uhci1 at pci0 dev <span style="color:#f99b15">26</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">21</span>
</span></span><span style="display:flex;"><span>ehci0 at pci0 dev <span style="color:#f99b15">26</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">7</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>usb0 at ehci0: USB revision 2.0
</span></span><span style="display:flex;"><span>uhub0 at usb0 <span style="color:#48b685">&#34;Intel EHCI root hub&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>azalia0 at pci0 dev <span style="color:#f99b15">27</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801H HD Audio&#34;</span> rev 0x02: msi
</span></span><span style="display:flex;"><span>azalia0: codecs: Sigmatel STAC9228X
</span></span><span style="display:flex;"><span>audio0 at azalia0
</span></span><span style="display:flex;"><span>ppb1 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801H PCIE&#34;</span> rev 0x02: msi
</span></span><span style="display:flex;"><span>pci2 at ppb1 bus <span style="color:#f99b15">11</span>
</span></span><span style="display:flex;"><span>ppb2 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Intel 82801H PCIE&#34;</span> rev 0x02: msi
</span></span><span style="display:flex;"><span>pci3 at ppb2 bus <span style="color:#f99b15">12</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Broadcom BCM4321&#34;</span> rev 0x03 at pci3 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>ppb3 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">3</span> <span style="color:#48b685">&#34;Intel 82801H PCIE&#34;</span> rev 0x02: msi
</span></span><span style="display:flex;"><span>pci4 at ppb3 bus <span style="color:#f99b15">13</span>
</span></span><span style="display:flex;"><span>ppb4 at pci0 dev <span style="color:#f99b15">28</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">5</span> <span style="color:#48b685">&#34;Intel 82801H PCIE&#34;</span> rev 0x02: msi
</span></span><span style="display:flex;"><span>pci5 at ppb4 bus <span style="color:#f99b15">9</span>
</span></span><span style="display:flex;"><span>bge0 at pci5 dev <span style="color:#f99b15">0</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Broadcom BCM5906M&#34;</span> rev 0x02, BCM5906 A2 <span style="color:#5bc4bf">(</span>0xc002<span style="color:#5bc4bf">)</span>: msi, address 00:1d:09:37:6d:1b
</span></span><span style="display:flex;"><span>brgphy0 at bge0 phy 1: BCM5906 10/100baseTX PHY, rev. <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>uhci2 at pci0 dev <span style="color:#f99b15">29</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">20</span>
</span></span><span style="display:flex;"><span>uhci3 at pci0 dev <span style="color:#f99b15">29</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">21</span>
</span></span><span style="display:flex;"><span>uhci4 at pci0 dev <span style="color:#f99b15">29</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">2</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">22</span>
</span></span><span style="display:flex;"><span>ehci1 at pci0 dev <span style="color:#f99b15">29</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">7</span> <span style="color:#48b685">&#34;Intel 82801H USB&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">20</span>
</span></span><span style="display:flex;"><span>usb1 at ehci1: USB revision 2.0
</span></span><span style="display:flex;"><span>uhub1 at usb1 <span style="color:#48b685">&#34;Intel EHCI root hub&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>ppb5 at pci0 dev <span style="color:#f99b15">30</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801BAM Hub-to-PCI&#34;</span> rev 0xf2
</span></span><span style="display:flex;"><span>pci6 at ppb5 bus <span style="color:#f99b15">3</span>
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Ricoh 5C832 Firewire&#34;</span> rev 0x05 at pci6 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> not configured
</span></span><span style="display:flex;"><span>sdhc0 at pci6 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Ricoh 5C822 SD/MMC&#34;</span> rev 0x22: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">18</span>
</span></span><span style="display:flex;"><span>sdhc0: SDHC 1.0, <span style="color:#f99b15">33</span> MHz base clock
</span></span><span style="display:flex;"><span>sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Ricoh 5C843 MMC&#34;</span> rev 0x12 at pci6 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">2</span> not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Ricoh 5C592 Memory Stick&#34;</span> rev 0x12 at pci6 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">3</span> not configured
</span></span><span style="display:flex;"><span><span style="color:#48b685">&#34;Ricoh 5C852 xD&#34;</span> rev 0x12 at pci6 dev <span style="color:#f99b15">1</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">4</span> not configured
</span></span><span style="display:flex;"><span>pcib0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;Intel 82801HBM LPC&#34;</span> rev 0x02
</span></span><span style="display:flex;"><span>pciide0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;Intel 82801HBM IDE&#34;</span> rev 0x02: DMA, channel <span style="color:#f99b15">0</span> configured to compatibility, channel <span style="color:#f99b15">1</span> configured to compatibility
</span></span><span style="display:flex;"><span>atapiscsi0 at pciide0 channel <span style="color:#f99b15">0</span> drive <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>scsibus1 at atapiscsi0: <span style="color:#f99b15">2</span> targets
</span></span><span style="display:flex;"><span>cd0 at scsibus1 targ <span style="color:#f99b15">0</span> lun 0: &lt;HL-DT-ST, DVD+-RW GSA-S10N, A103&gt; ATAPI 5/cdrom removable
</span></span><span style="display:flex;"><span>cd0<span style="color:#5bc4bf">(</span>pciide0:0:0<span style="color:#5bc4bf">)</span>: using PIO mode 4, Ultra-DMA mode <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>pciide0: channel <span style="color:#f99b15">1</span> ignored <span style="color:#5bc4bf">(</span>disabled<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>ahci0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">2</span> <span style="color:#48b685">&#34;Intel 82801HBM AHCI&#34;</span> rev 0x02: msi, AHCI 1.1
</span></span><span style="display:flex;"><span>ahci0: port 0: 3.0Gb/s
</span></span><span style="display:flex;"><span>ahci0: PHY offline on port <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>scsibus2 at ahci0: <span style="color:#f99b15">32</span> targets
</span></span><span style="display:flex;"><span>sd0 at scsibus2 targ <span style="color:#f99b15">0</span> lun 0: &lt;ATA, TOSHIBA MQ01ABF0, AM0G&gt; SCSI3 0/direct fixed naa.5000039523783257
</span></span><span style="display:flex;"><span>sd0: 476940MB, <span style="color:#f99b15">512</span> bytes/sector, <span style="color:#f99b15">976773168</span> sectors
</span></span><span style="display:flex;"><span>ichiic0 at pci0 dev <span style="color:#f99b15">31</span> <span style="color:#815ba4">function</span> <span style="color:#f99b15">3</span> <span style="color:#48b685">&#34;Intel 82801H SMBus&#34;</span> rev 0x02: apic <span style="color:#f99b15">2</span> int <span style="color:#f99b15">17</span>
</span></span><span style="display:flex;"><span>iic0 at ichiic0
</span></span><span style="display:flex;"><span>spdmem0 at iic0 addr 0x50: 2GB DDR2 SDRAM non-parity PC2-6400CL6 SO-DIMM
</span></span><span style="display:flex;"><span>spdmem1 at iic0 addr 0x52: 2GB DDR2 SDRAM non-parity PC2-5300CL5 SO-DIMM
</span></span><span style="display:flex;"><span>usb2 at uhci0: USB revision 1.0
</span></span><span style="display:flex;"><span>uhub2 at usb2 <span style="color:#48b685">&#34;Intel UHCI root hub&#34;</span> rev 1.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>usb3 at uhci1: USB revision 1.0
</span></span><span style="display:flex;"><span>uhub3 at usb3 <span style="color:#48b685">&#34;Intel UHCI root hub&#34;</span> rev 1.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>usb4 at uhci2: USB revision 1.0
</span></span><span style="display:flex;"><span>uhub4 at usb4 <span style="color:#48b685">&#34;Intel UHCI root hub&#34;</span> rev 1.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>usb5 at uhci3: USB revision 1.0
</span></span><span style="display:flex;"><span>uhub5 at usb5 <span style="color:#48b685">&#34;Intel UHCI root hub&#34;</span> rev 1.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>usb6 at uhci4: USB revision 1.0
</span></span><span style="display:flex;"><span>uhub6 at usb6 <span style="color:#48b685">&#34;Intel UHCI root hub&#34;</span> rev 1.00/1.00 addr <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>isa0 at pcib0
</span></span><span style="display:flex;"><span>isadma0 at isa0
</span></span><span style="display:flex;"><span>pckbc0 at isa0 port 0x60/5 irq <span style="color:#f99b15">1</span> irq <span style="color:#f99b15">12</span>
</span></span><span style="display:flex;"><span>pckbd0 at pckbc0 <span style="color:#5bc4bf">(</span>kbd slot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wskbd0 at pckbd0: console keyboard, using wsdisplay0
</span></span><span style="display:flex;"><span>pms0 at pckbc0 <span style="color:#5bc4bf">(</span>aux slot<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>wsmouse0 at pms0 mux <span style="color:#f99b15">0</span>
</span></span><span style="display:flex;"><span>pms0: Synaptics touchpad, firmware 6.3
</span></span><span style="display:flex;"><span>pcppi0 at isa0 port 0x61
</span></span><span style="display:flex;"><span>spkr0 at pcppi0
</span></span><span style="display:flex;"><span>uvideo0 at uhub1 port <span style="color:#f99b15">6</span> configuration <span style="color:#f99b15">1</span> interface <span style="color:#f99b15">0</span> <span style="color:#48b685">&#34;OmniVision Technologies, Inc. -2640-07.07.20.3 Laptop Integrated Webcam&#34;</span> rev 2.00/1.00 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>video0 at uvideo0
</span></span><span style="display:flex;"><span>ugen0 at uhub6 port <span style="color:#f99b15">1</span> <span style="color:#48b685">&#34;STMicroelectronics Biometric Coprocessor&#34;</span> rev 1.00/0.01 addr <span style="color:#f99b15">2</span>
</span></span><span style="display:flex;"><span>vscsi0 at root
</span></span><span style="display:flex;"><span>scsibus3 at vscsi0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>softraid0 at root
</span></span><span style="display:flex;"><span>scsibus4 at softraid0: <span style="color:#f99b15">256</span> targets
</span></span><span style="display:flex;"><span>root on sd0a <span style="color:#5bc4bf">(</span>7d76cb4c2570dde6.a<span style="color:#5bc4bf">)</span> swap on sd0b dump on sd0b
</span></span></code></pre></div><h2 id="hwsensors">hw.sensors</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>hw.sensors.cpu0.temp0<span style="color:#5bc4bf">=</span>69.00 degC
</span></span><span style="display:flex;"><span>hw.sensors.acpitz0.temp0<span style="color:#5bc4bf">=</span>54.50 degC <span style="color:#5bc4bf">(</span>zone temperature<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpibtn0.indicator0<span style="color:#5bc4bf">=</span>On <span style="color:#5bc4bf">(</span>lid open<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>hw.sensors.acpiac0.indicator0<span style="color:#5bc4bf">=</span>On <span style="color:#5bc4bf">(</span>power supply<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><hr>
]]></content>
        <summary type="html"><![CDATA[Récapitulatif de ce qui fonctionne ou pas sur un Dell XPS M1330 sous OpenBSD]]></summary>
        <published>2016-12-10T20:42:12+02:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:8ed45d45-c583-1602-04f4-171f94bf3616</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/firefox/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Firefox / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Firefox" scheme="http://doc.huc.fr.eu.org/fr/tags/firefox/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>[Firefox]https://www.mozilla.org/firefox/)</strong> est un navigateur web
conforme aux normes, pleinement équipé, construit sur la base du code de
Mozilla par des centaines de contributeurs dans le monde. Il est
extensible à travers des centaines d&rsquo;extensions, contributions
d&rsquo;utilisateurs, et de fonctionnalités :</p>
<ul>
<li>Navigation par onglets améliorée, avec regroupement des onglets</li>
<li>Navigation privée</li>
<li>Vérification orthographique</li>
<li>Suggestions de recherche</li>
<li>Restauration de session</li>
<li>Lecteurs Web (RSS)</li>
<li>Titres en direct</li>
<li>Recherche intégrée</li>
<li>Signets en direct</li>
<li>Bloqueur de Pop-up</li>
<li>Protection contre le phishing</li>
<li>Gestionnaire de Moteurs de Recherche</li>
</ul>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>firefox</code></strong>.</p>
<h2 id="configuration">Configuration</h2>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>La plupart des informations de configuration ci-dessous concernent
Firefox Quantum- moteur du navigateur à partir de la v57 !</p>
<p>Merci d&rsquo;en tenir compte.</p>
</div>

<h3 id="d-bus">D-Bus</h3>
<p>Pour une intégration propre avec les composants des environnements de
bureau, Firefox a besoin d&rsquo;une instance de D-Bus fonctionnelle.</p>
<p>Veuillez lire <a class="inside" href="/fr/sys/openbsd/dbus/" title="Lien interne vers l&#39;article : 'D-Bus [système de bus de messages] / OpenBSD'">D-Bus [système de bus de messages] / OpenBSD</a></p>
<h3 id="doh">DoH</h3>
<p><strong>Cette option est disponible à partir de la v63.0 !</strong></p>
<p>Pour activer DNS-sur-HTTPS (DoH: DNS-over-HTTPS), ouvrez les
<a href="/fr/sys/openbsd/firefox/#aboutpreferences">préférences</a></p>
<ul>
<li>Menu &ldquo;Général&rdquo;</li>
<li>Déroulez jusqu&rsquo;à la section &ldquo;Paramètres réseau&rdquo;</li>
<li>Cliquez sur le bouton [ <u>P</u>aramètres… ]</li>
<li>Déroulez jusqu&rsquo;à la case à cocher &ldquo;Activer DNS sur HTTPS&rdquo; ; cochez la
case !</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Il semble préférable de modifier l&rsquo;URL proposée par défaut… retrouvez
des adresses de serveurs DNS gérant DoH, par exemple, sur :</p>
<ul>
<li><a href="https://doh.defaultroutes.de/#sec-5" rel="external">https://doh.defaultroutes.de/#sec-5</a></li>
<li><a href="https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers" rel="external">https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers</a></li>
</ul>
<p>Cette URL est paramétrable aussi par le biais de l'
<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a> ; cherchez puis modifiez la valeur
<code>network.trr.uri</code>.</p>
</div>

<hr>
<p>L&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a> permet de
modifier les valeurs des Résolveurs Récursifs de Confiance
<em>(en anglais : 

































































































<span lang="en">TRR <em>(Trusted Recursive Resolvers)</em></span>













)</em>.</p>
<ul>
<li>
<p><code>network.trr.mode</code> :</p>
<ul>
<li><code>0</code> : défaut, <code>off</code></li>
<li><code>1</code> : mode <code>race</code></li>
<li><code>2</code> : TRR en premier</li>
<li><code>3</code> : TRR seulement</li>
<li><code>4</code> : mode <code>shadow</code></li>
<li><code>5</code> : désactivé par choix.</li>
</ul>
</li>
</ul>
<hr>
<h4 id="informations">Informations</h4>
<ul>
<li>[Doh] Mozilla&rsquo;s plans : <a href="https://mailarchive.ietf.org/arch/msg/doh/po6GCAJ52BAKuyL-dZiU91v6hLw" rel="external">Archive</a></li>
<li><a href="https://wiki.mozilla.org/Security/DOH-resolver-policy" rel="external">Security/DOH-resolver-policy</a></li>
<li><a href="https://wiki.mozilla.org/Trusted_Recursive_Resolver" rel="external">Trusted Recursive Resolver</a></li>
</ul>
<h3 id="fidou2f">FIDO/U2F</h3>
<p>OpenBSD 6.7 apporte la gestion de clés USB respectant la norme FIDO,
permettant ainsi la double authentification U2F.</p>
<p>Firefox supporte U2F depuis la version 60.0 et supérieure. Néanmoins, il peut
être utile de vérifier sa <a href="/fr/sys/openbsd/firefox/#aboutconfig">configuration</a> et s&rsquo;assurer que la
variable de type booléenne <code>security.webauth.u2f</code> soit bien configurée sur <code>true</code>.</p>
<p>Ensuite, tout site web qui propose l&rsquo;authentification U2F devrait être
capable de voir la clé U2F, après la saisie de mots de passe :</p>
<ul>
<li>pour la phase de reconnaissance,</li>
<li>puis, pour permettre l&rsquo;authentification</li>
</ul>
<p><em>(Exemples de site supportant la 2FA U2F : GitHub, GitLab, …)</em></p>
<h3 id="accélération-graphique">Accélération Graphique</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>Ces fonctionnalités ne sont utilisables qu&rsquo;avec Firefox Quantum, et
tout particulièrement à partir de la version 59.x !</strong></p>
<p><strong>Il est important que votre architecture matérielle gère
OpenGL 4, et WebGL 2 ; autrement, OUBLIEZ !</strong></p>
</div>

<p>⇒ Par défaut, l&rsquo;accélération graphique OpenGL est désactivée. Il est
possible de l&rsquo;activer de deux manières :</p>
<ul>
<li>Ajoutez à votre environnement la variable suivante : <code>MOZ_ACCELERATED=1</code></li>
<li>L&rsquo;autre moyen étant d&rsquo;utiliser l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>
et de modifier la valeur binaire <code>layers.acceleration.force-enable</code>
pour la positionner sur <code>true</code>.</li>
<li>Pour vérifier le <a href="/fr/sys/openbsd/firefox/#aboutsupport">support</a>, cherchez les champs <code>HW_COMPOSITING</code>
et <code>OPENGL_COMPOSITING</code> dans la section <strong>Accélération graphique</strong>.</li>
</ul>
<p>⇒ Pour activer le compositeur basé sur Rust, deux manières possibles :</p>
<ul>
<li>Ajoutez à votre environnement la variable suivante : <code>MOZ_WEBRENDER=1</code></li>
<li>L&rsquo;autre moyen étant d&rsquo;utiliser l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>
et de modifier la valeur binaire <code>gfx.webrender.enabled</code> pour la
positionner sur <code>true</code>.</li>
<li>Pour vérifier le <a href="/fr/sys/openbsd/firefox/#aboutsupport">support</a>, cherchez le
champ <code>WEBRENDER</code> dans la section <strong>Accélération graphique</strong>.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Si vous voulez avoir plus de détails, lisez : <br>
<a href="https://wiki.mozilla.org/Platform/GFX/Quantum_Render" rel="external">https://wiki.mozilla.org/Platform/GFX/Quantum_Render</a>  !</div>

<h3 id="audio-vidéo-html5">Audio, Vidéo HTML5</h3>
<p>Pour <strong>ajouter le support audio et vidéo HTML5</strong>,
<strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code><a class="inside" href="/fr/sys/openbsd/ffmpeg/" title="Lien interne vers l&#39;article : 'FFmpeg / OpenBSD'">ffmpeg</a>
</code></strong>.</p>
<h4 id="module-complémentaire">Module complémentaire</h4>
<p>Vous pouvez ajouter le module
<strong><a href="https://addons.mozilla.org/en-US/firefox/addon/html5-video-everywhere-next/" rel="external">HTML5 Video Everywhere!</a></strong>
qui améliorera la lecture vidéo en favorisant celle-ci par le biais d&rsquo;un
lecteur vidéo HTML5 - <em>utile, par exemple, pour les lectures Youtube</em>…</p>
<h3 id="kerberosv">KerberosV</h3>
<p>Pour utiliser Firefox en mode KerberosV :</p>
<ul>
<li>il faut <strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>

le paquet <code>heimdal</code></strong>.</li>
<li>puis configurer votre client Kerberos.</li>
<li>ajouter à votre environnement la variable <code>LD_LIBRARY_PATH=/usr/local/heimdal/lib</code>
<ul>
<li><em>ceci peut être fait de multiple façons, via le shell, via un script…</em></li>
<li>ou modifier <code>shlib_dirs</code> au fichier <code>/etc/rc.conf.local</code></li>
</ul>
</li>
</ul>
<p>Si vous désirez spécifier l&rsquo;usage de Kerberos en ciblant certains domaines,
utilisez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a> puis
modifiez la clé <code>network.negotiate-auth.trusted-uris</code> en ajoutant votre
domaine, tel que : <br>
<code>.example.com</code>.</p>
<h3 id="langue-française">Langue Française</h3>
<h4 id="-v69">≥ v69</h4>
<p>Depuis Firefox v69.0.2, sous OpenBSD 6.6, il est possible de changer en
choisissant le menu &ldquo;<a href="/fr/sys/openbsd/firefox/#aboutpreferences">préférences</a>&rdquo;,
onglet &lsquo;General&rsquo; &gt; Language, puis cliquez sur la liste déroulante pour
ajouter une nouvelle langue.</p>
<p>Vous aurez une nouvelle fenêtre qui s&rsquo;affiche qui vous permettra
d&rsquo;ajouter &lsquo;French&rsquo; ; validez votre choix par l&rsquo;appui sur le bouton [ OK ].</p>
<p>Redémarrez Firefox, et voilà !</p>
<h4 id="-v59">≥ v59</h4>
<p>Pour Firefox v59 ou supérieure :</p>
<ul>
<li>Installez le module <strong>Français Language Pack</strong> !</li>
<li>Activez la gestion de la langue française : menu <code>Tools</code> &gt; <code>Add-ons</code> &gt; <code>Language</code></li>
<li>Ensuite, ouvrez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>
puis créer|chercher la variable de type &lsquo;String&rsquo; <code>intl.locale.requested</code>
et la mettre à <code>fr-FR</code></li>
</ul>
<h4 id="-v56">≥ v56</h4>
<p>⇒ Pour Firefox, inférieure ou égale à v56 :</p>
<ul>
<li>Allez dans les <a href="/fr/sys/openbsd/firefox/#aboutpreferences">préférences</a>, puis
activer la langue française dans la partie &ldquo;Contenu&rdquo;</li>
<li>ouvrez ensuite l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>,
puis cherchez <code>general.useragent.locale</code> et mettre à <code>fr-FR</code>.</li>
</ul>
<h4 id="paquets-supplémentaires">Paquets supplémentaires</h4>
<p>Vous pouvez aussi essayer à <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 :</p>
<ul>
<li><strong>le paquet <code>firefox-i18n-fr</code></strong>.</li>
<li>le module <strong>Français Language Pack</strong> :
<ul>
<li><strong>OpenBSD v6.3</strong> : <strong><a href="https://addons.mozilla.org/fr/firefox/addon/fran%C3%A7ais-language-pack/versions/59.0" rel="external">version 59</a></strong></li>
<li><strong>OpenBSD v6.2</strong> : <strong><a href="https://addons.mozilla.org/fr/firefox/addon/fran%C3%A7ais-language-pack/versions/56.0" rel="external">version 56</a></strong></li>
</ul>
</li>
<li>le package <strong>mozilla-dicts-fr</strong>, qui est le package additionnel, non
nécessaire, du dictionnaire français…</li>
</ul>
<h3 id="liens-mailto">Liens mailto</h3>
<p>À-propos de la <strong>gestion des liens mailto</strong> :</p>
<ul>
<li>Ouvrez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>, et
cherchez l&rsquo;option <code>network.protocol-handler.app.mailto</code>.
<ul>
<li>si elle existe, vérifiez le chemin absolu de votre client mail, tel
que : <code>/usr/local/bin/thunderbird</code></li>
<li>sinon créez-la en ajoutant une &ldquo;nouvelle chaîne&rdquo; <em>(<code>new string</code>)</em></li>
</ul>
</li>
</ul>
<h3 id="extensions">Extensions</h3>
<h4 id="keepassxc-browser">KeePassXC-Browser</h4>
<p>Depuis OpenBSD 6.6, le logiciel de confidentialité
<strong><a class="inside" href="/fr/sys/openbsd/keepassxc/" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC</a>
</strong> est installable.</p>
<p>Pour fonctionner correctement avec Firefox, il est nécessaire d&rsquo;installer
le module <strong>KeePassXC-Browser</strong>.</p>
<ul>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/keepassxc-browser/" rel="external">https://addons.mozilla.org/fr/firefox/addon/keepassxc-browser/</a></li>
</ul>
<p>Lire la page <strong>KeePassXC</strong> pour avoir plus d&rsquo;informations concernant le
module  <a class="inside" href="/fr/sys/openbsd/keepassxc/#keepassxc-browser" title="Lien interne vers l&#39;article : 'KeepassXC : outil de gestion de données sensibles / OpenBSD'">KeePassXC-Browser</a>
</p>
<h5 id="unveil-et-keepassxc-proxy">Unveil et KeePassXC Proxy</h5>
<p>Ajouter au <a href="/fr/sys/openbsd/firefox/#support-pledge-et-unveil">fichier de configuration unveil</a>
de firefox <code>unveil.main</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin r</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">/usr/local/bin/keepassxc-proxy rx</span>
</span></span></code></pre></div><p>Ainsi le proxy de KeePassXC pourra communiquer avec le module
KeePassXC-Browser.</p>
<h3 id="recherche-openbsd-manpage">Recherche OpenBSD Manpage</h3>
<p>Retrouvez un module pour effectuer une recherche sur le site officiel
OpenBSD Manual page :</p>
<ul>
<li><strong>OpenBSD Manpage</strong> : <a href="https://addons.mozilla.org/addon/openbsd-manpage/" rel="external">https://addons.mozilla.org/addon/openbsd-manpage/</a></li>
</ul>
<h3 id="multi-processus">Multi-processus</h3>
<p>Pour <strong>activer la gestion de la fonctionnalité des multi-processus</strong>,
ouvrez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>, puis :</p>
<ul>
<li>vérifiez l&rsquo;option <code>browser.tabs.remote.force-enable</code>
<ul>
<li><em>au besoin, si elle n&rsquo;existe pas, créez-la</em> - et positionnez-la à
<code>true</code> ;</li>
</ul>
</li>
<li>positionnez l&rsquo;option <code>browser.tabs.remote.autostart</code> à <code>true</code> ;</li>
</ul>
<p>Puis, vérifiez le <a href="/fr/sys/openbsd/firefox/#aboutsupport">support</a>, dans la
section &ldquo;Paramètres de base de l’application&rdquo;, vous devriez lire à
&ldquo;Fenêtres multi-processus     1/1 (Activé par l’utilisateur)&rdquo; -
<em>sinon, cela ne fonctionne pas</em> !</p>
<h3 id="support-pledge-et-unveil">Support Pledge et Unveil</h3>
<p>Firefox sur OpenBSD est sécurisé par pledge(2) et unveil(2) - afin de
limiter les appels systèmes et les accès au système de fichier.</p>
<p>Par défaut, seuls les répertoires <code>/tmp</code> et <code>~/Downloads</code> sont autorisés
en écriture. De même, la lecture des fichiers locaux est autorisé en
préfixant le chemin vers le fichier par <code>file://</code>.</p>
<p>Si votre répertoire personnel <code>~/Downloads</code> n&rsquo;existe pas, créez-le puis
relancez Firefox.</p>
<ul>
<li>Depuis OpenBSD 6.7 : unveil est activé par défaut
<ul>
<li><em>présent depuis la version -current la précédant</em>.</li>
</ul>
</li>
<li>Avant OpenBSD 6.7 : Par défaut, unveil est désactivé !</li>
</ul>
<p>Les permissions pour chaque type de processus sont localisées par défaut
dans des fichiers contenus dans <code>/etc/firefox</code> qui est une copie de
<code>/usr/local/lib/firefox/browser/defaults/preferences/</code> lors de
l&rsquo;installation, principalement :</p>
<ul>
<li><code>/etc/firefox/pledge.main</code></li>
<li><code>/etc/firefox/unveil.main</code></li>
</ul>
<h4 id="gestion-mime-paquets-tiers">Gestion MIME paquets tiers</h4>
<p>Du fait d&rsquo;unveil(2), il est nécessaire de gérer finement les gestionnaires
MIME.</p>
<p>Par exemple pour permettre l&rsquo;utilisation d&rsquo;un lecteur PDF avec Firefox,
il faut :</p>
<ol>
<li>
<p>déclarer par défaut le lecteur PDF en tant gestionnaire MIME, tel que</p>
<ul>
<li>pour xpdf : <code>$ xdg-mime default xpdf.desktop application/pdf</code></li>
<li>pour mupdf : <code>$ xdg-mime default mupdf.desktop application/pdf</code></li>
</ul>
</li>
<li>
<p>modifier le fichier <code>/etc/firefox/unveil.main</code> pour gérer les droits
sur le binaire correspondant, tel que :</p>
<ul>
<li>pour xpdf : <code>/usr/local/bin/xpdf rx</code></li>
<li>pour mupdf : <code>/usr/local/bin/mupdf rx</code></li>
</ul>
</li>
</ol>
<p>Ainsi vous pourrez lire le fichier PDF avec l&rsquo;option &ldquo;Ouvrir avec…&rdquo;.</p>
<hr>
<p><code>$ xdg-mime query default application/pdf</code> permet de connaître le lecteur
PDF par défaut.</p>
<h3 id="webrtc">WebRTC</h3>
<p>Le support des webcams est normalement géré par Firefox, qui par défaut
a accès aux périphériques vidéo  <code>/dev/video</code> et <code>/dev/video0</code>.</p>
<p>⇒ <strong>OpenBSD ≥ 6.9</strong> : Il faut aussi :
- activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-video/#enregistrement-video" title="Lien interne vers l&#39;article : 'Gérer la vidéo sous OpenBSD'">enregistrement vidéo</a>

- puis <a class="inside" href="/fr/sys/openbsd/tip-webcam/#enregistrement-video" title="Lien interne vers l&#39;article : 'Webcam / OpenBSD'">vérifier le support et accéder à la webcam</a>

- et pour finir l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-audio/#enregistrement-audio" title="Lien interne vers l&#39;article : 'Gestion du Son / OpenBSD'">enregistrement audio</a>
.</p>
<p>⇒ <strong>OpenBSD ≥ 6.4</strong> : Pour que la fonctionnalité WebRTC fonctionne
correctement, il faut activer l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-audio/#enregistrement-audio" title="Lien interne vers l&#39;article : 'Gestion du Son / OpenBSD'">enregistrement audio</a>
.</p>
<hr>
<h2 id="dépannage">Dépannage</h2>
<h3 id="aboutconfig">about:config</h3>
<p>L&rsquo;éditeur de configuration est accessible en écrivant dans la barre
d&rsquo;URL : <code>about:config</code>.</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>L&rsquo;édition de la configuration comporte des risques ; en effet, une
mauvaise configuration peut rendre instable ou empêcher le logiciel de
fonctionner.</p>
<p>Une fois la configuration modifiée, il est important de <strong>redémarrer le
logiciel</strong> !</p>
</div>

<h3 id="aboutpreferences">about:preferences</h3>
<p>Les <strong>Préférences</strong> sont accessibles de deux manières :</p>
<ul>
<li>Par le menu &ldquo;Édition&rdquo; &gt; &ldquo;Préférences&rdquo;</li>
<li>ou, en écrivant dans la barre d&rsquo;URL : <code>about:preferences</code></li>
</ul>
<h3 id="aboutsupport">about:support</h3>
<p>La page <strong>Informations de dépannage</strong> est accessible en écrivant dans la
barre d&rsquo;URL : <code>about:support</code>.</p>
<p>Cette page contient des informations techniques qui permettent de
vérifier le support de certaines fonctionnalités et d&rsquo;aider à résoudre
certains problèmes !</p>
<h3 id="débogage">Débogage</h3>
<p>Veuillez ABSOLUMENT lire le fichier pkg-readme de Firefox, pour savoir
comment faire pour remonter tout problème rencontré, si Firefox crashe
régulièrement.</p>
<p>Attention, tout rapport de bogue envoyé sans les informations nécessaires
et demandées dans la section &ldquo;Debugging&rdquo; sera purement et simplement ignoré !</p>
<h3 id="firefox-ne-démarre-pas">Firefox ne démarre pas</h3>
<p><strong>Si Firefox ne démarre pas</strong>, essayez de le démarrer en mode console,
avec l&rsquo;option <code>-safe-mode</code> - <em>cela aura pour effet d&rsquo;essayer à le
démarrer après avoir désactivé toutes vos extensions, vos thèmes.</em></p>
<h3 id="firefox-a-un-comportement-étrange">Firefox a un comportement étrange</h3>
<p><strong>Si Firefox a un comportement étrange</strong>, essayez de créer un nouveau
profil :</p>
<ul>
<li>soit, vous redémarrez Firefox en mode console, en utilisant l&rsquo;option
<code>-ProfileManager</code>, puis vous cliquez sur [ Create Profile ]</li>
<li>soit, vous écrivez &ldquo;about:profiles&rdquo; dans la barre d&rsquo;URL, puis vous
cliquez sur le bouton [ Créer un nouveau profil ].</li>
</ul>
<h3 id="firefox-et-firefox-esr-en-même-temps">Firefox et firefox-esr en même temps</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Vous ne pouvez faire fonctionner les deux versions en même temps, si
vous n&rsquo;avez pas de profils d&rsquo;exécution différents.</div>

<p>Pour exécuter les deux versions en même temps, la version
<strong><a class="inside" href="/fr/sys/openbsd/firefox-esr/" title="Lien interne vers l&#39;article : 'Firefox ESR / OpenBSD'">Firefox ESR</a>
</strong>
et celle-ci, vous devez créer des profils différents :</p>
<ul>
<li>Pour firefox : <code>firefox -p</code></li>
<li>Pour firefox-esr : <code>firefox-esr -p</code></li>
</ul>
<p>Il suffit de créer et d&rsquo;attribuer un profil différent…</p>
<h3 id="impression">Impression</h3>
<p>Êtes-vous sûr d&rsquo;avoir installé le paquet <a class="inside" href="/fr/sys/openbsd/cups/" title="Lien interne vers l&#39;article : 'Cups : Gestion de l&#39;impression sous OpenBSD'">CUPS</a>

et <code>gtk+2-cups</code> ou son pendant <code>gtk+3-cups</code> ?</p>
<h3 id="ipv4--ipv6">IPv4 / IPv6</h3>
<p>Vous avez besoin de consulter certains sites juste sur le protocole IPv4 ?</p>
<p>Ouvrez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a> et
paramétrez la variable <code>network.dns.ipv4OnlyDomains</code>. Si vous voulez
gérer plusieurs domaines, séparez-les par une virgule.</p>
<h3 id="prefers-color-scheme">prefers-color-scheme</h3>
<p>Cette <a href="https://developer.mozilla.org/fr/docs/Web/CSS/@media/prefers-color-scheme" rel="external">caractéristique de média CSS</a>
est fonctionnelle à partir de la v67.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Si l&rsquo;option de <a href="/fr/sys/openbsd/firefox/#aboutconfig">configuration</a> de confidentialité relative à la
prise d&rsquo;empreinte <code>privacy.resistFingerprinting</code> est paramétrée sur <code>true</code>, la
gestion de cette option ne fonctionnera pas ; ce sera le schéma <code>light</code> qui
sera choisi par défaut.</div>

<p>L&rsquo;option de préférence du schéma de couleurs <code>prefers-color-scheme</code> doit
être activé par l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>.</p>
<p>Créez une valeur numérique <code>ui.systemUsesDarkTheme</code> en lui donnant pour valeur <code>1</code>.</p>
<h3 id="protonmail">Protonmail</h3>
<p>Vous n&rsquo;arrivez pas à vous connecter au service web de Protonmail.com !</p>
<p>Ouvrez l&rsquo;<a href="/fr/sys/openbsd/firefox/#aboutconfig">éditeur de configuration</a>, puis
positionnez l&rsquo;option <code>javascript.options.asmjs</code> sur <code>false</code> -
<em>(<a href="http://www.vincentdelft.be/post/post_20181001" rel="external">source</a>)</em></p>
<h2 id="documentation">Documentation</h2>
<p>Après l&rsquo;installation, n&rsquo;oubliez pas de <strong>lire le fichier</strong> : <br>
<code>/usr/local/share/doc/pkg-readmes/firefox</code></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le navigateur web Firefox sous OpenBSD]]></summary>
        <published>2016-12-10T16:44:39+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ee999d19-97e9-3b6e-571e-fe846122b44f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/after-install/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Que faire après l&#39;installation d’OpenBSD ?</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="envoyer-votre-dmesg-aux-développeurs">Envoyer votre dmesg aux développeurs</h2>
<p>Si vous voulez aider à l&rsquo;amélioration du support matériel d&rsquo;OpenBSD, ça
ne prend que quelques minutes.</p>
<ul>
<li>Lancez la commande <code>(dmesg; sysctl hw.sensors) &gt; ~/dmesg.txt</code></li>
<li>Envoyez le fichier <code>dmesg.txt</code> à <code>dmesg@openbsd.org</code>, avec quelques
informations supplémentaires sur ce qui fonctionne ou non.</li>
</ul>
<p><a href="https://openbsd.org/faq/faq4.html#%23SendDmesg" rel="external">Plus d&rsquo;infos sur la FAQ</a>.</p>
<h2 id="accélérer-le-disque-dur-avec-les-soft-updates">Accélérer le disque-dur avec les soft-updates</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>À partir d&rsquo;OpenBSD 7.4, l&rsquo;option <code>softdep</code> n&rsquo;est plus opérationnelle.</p>
<p>Cf: <a href="https://undeadly.org/cgi?action=article;sid=20230706044554" rel="external">1</a>,
<a href="https://www.linuxquestions.org/questions/%2Absd-17/openbsd-soft-updates-softdep-disabled-for-future-vfs-work-4175726674/#post6440478" rel="external">2</a></p>
</div>

<p>Ajoutez l&rsquo;option <a href="https://openbsd.org/faq/faq14.html#SoftUpdates" rel="external"><code>softdep</code></a>
dans le fichier <code>/etc/fstab</code> sur chaque ligne pour qu’elles ressemblent
à ça :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">/dev/sd0a / ffs rw,softdep 1 1</span>
</span></span></code></pre></div><hr>
<p>De même, on peut rajouter l&rsquo;option <code>noatime</code>, ce qui donne :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">/dev/sd0a / ffs rw,softdep,noatime 1 1</span>
</span></span></code></pre></div>
<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>Attention</strong> à l&rsquo;usage de cette option, dans certains contextes, elle
peut être dangereuse car elle désactive la journalisation des informations
relatives aux modifications dans le système de fichier.</p>
<p>Elle peut être utile dans le contexte d&rsquo;usage de disque de type SSD,
afin d&rsquo;aider à ne pas les &ldquo;user&rdquo; prématurément…</p>
<p>Si vous décidez de l&rsquo;utiliser, soyez attentif à tout dysfonctionnement
de votre système d&rsquo;exploitation !</p>
</div>

<h2 id="lire-les-conseils">Lire les conseils</h2>
<h3 id="afterboot">afterboot</h3>
<p>La toute première source d&rsquo;information disponible, nécessaire à consulter,
juste après une installation, est celle-ci :</p>
<p><code>$ man afterboot</code></p>
<h3 id="pkg-readme">pkg-readme</h3>
<p>Les &lsquo;pkg-readme&rsquo; sont les fichiers readme liés à un binaire, utilisables
après l&rsquo;installation du binaire lié :</p>
<p><code>$ less /usr/local/share/doc/pkg-readmes/pkg_name</code></p>
<p>&lsquo;pkg_name&rsquo; étant le nom du binaire…
En effet, certaines informations pertinentes sont restituées dans ces
fichiers &lsquo;readme&rsquo; et expliquées clairement…</p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert"><p><strong>Astuce</strong> : si vous avez un environnement graphique, tel que
<a class="inside" href="/fr/sys/opebsd/xfce/" title="Lien interne vers l&#39;article : ''">XFCE</a>
, pourquoi pas créer un lien
symbolique vers le répertoire <code>/usr/local/share/doc/pkg-readmes/</code>, sur
votre &ldquo;bureau&rdquo; ;-)</p>
<p><code>$ ln -s /usr/local/share/doc/pkg-readmes/ ~/Desktop/</code></p>
</div>

<h2 id="autres-informations">Autres informations</h2>
<h3 id="kit-de-survie">Kit de survie</h3>
<p>Il peut être très utile, voire indispensable, de lire notre
<a class="inside" href="/fr/sys/openbsd/kit-survie/" title="Lien interne vers l&#39;article : 'Kit de survie sous OpenBSD'">Kit de survie sous OpenBSD</a> :D</p>
<h3 id="trucs--astuces">Trucs &amp; Astuces</h3>
<p>Retrouvez aussi tous nos <a class="inside" href="/fr/sys/openbsd/tips/" title="Lien interne vers l&#39;article : 'Trucs et astuces pour OpenBSD'">Trucs et astuces pour OpenBSD</a>, bien utiles,
pour démarrer…</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Votre installation d&#39;OpenBSD est terminée ! Voici quelques suggestions d&#39;actions à faire ensuite…]]></summary>
        <published>2016-12-10T16:40:23+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2e17ca65-a105-a8f7-5193-9c658e4049d6</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/apm/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Apm : Programme de contrôle de la gestion de l&#39;énergie et de l&#39;hibernation</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="apm" scheme="http://doc.huc.fr.eu.org/fr/tags/apm/" />
        <content type="html"><![CDATA[<h2 id="configuration">Configuration</h2>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#activer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Activer le service</a>
 <strong>apmd</strong>.</li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#param%c3%a9trer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Paramétrer</a>
 le
service <code>apmd</code> pour le mode d&rsquo;ajustement automatique des
performances : <code>-A</code></li>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#d%c3%a9marrer" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Démarrer le service</a>
 <strong>apmd</strong>.</li>
</ul>
<hr>
<ul>
<li>Pour suspendre l&rsquo;ordinateur, lancez : <code>apm -S</code>.</li>
<li>Pour faire hiberner l&rsquo;ordinateur, lancez : <code>apm -Z</code>.</li>
</ul>
<hr>
<p>Pensez à modifier l&rsquo;ordre d&rsquo;exécution des services pour que
<a class="inside" href="/fr/sys/openbsd/consolekit/" title="Lien interne vers l&#39;article : 'Consolekit2 (bus de messages) / OpenBSD'">messagebus</a>

démarre en premier :</p>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/rcctl/#ordonner" title="Lien interne vers l&#39;article : 'rcctl : configurer et contrôler les services sous OpenBSD'">Ordonner les services</a>
 <code>messagebus apmd</code>.</li>
</ul>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/apm/#man-8-apm">man 8 apm</a></li>
</ul>
<h3 id="man-8-apm">man 8 apm</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>apm</strong> [<strong>-AabHLlmPSvZz</strong>] [<strong>-f</strong> <strong>sockname</strong>] <br>
<strong>zzz</strong> [<strong>-SZz</strong>] [<strong>-f</strong> <strong>sockname</strong>] <br>
<strong>ZZZ</strong> [<strong>-SZz</strong>] [<strong>-f</strong> <strong>sockname</strong>] \</p>
<h4 id="description">Description</h4>
<p><strong>apm</strong> communique avec le service de gestion avancée d&rsquo;énergie
<a href="https://man.openbsd.org/apmd.8" rel="external">apmd(8)</a>, faisant des requêtes du statut
actuel de l&rsquo;énergie, ou permettre de mettre le système en étant d&rsquo;hibernation
ou de veille. <br>
Sans aucun drapeau, apm affiche l&rsquo;état actuel de la gestion d&rsquo;énergie avec
des messages détaillés.</p>
<p><strong>Pour connaître les options, lisez le <a href="https://man.openbsd.org/apm.8" rel="external">manpage apm(8)</a> !</strong></p>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><code>/var/run/apmdev</code> : Le socket de communication par défaut sous Unix,
avec <a href="https://man.openbsd.org/apmd.8" rel="external">apmd(8)</a>. Le drapeau <code>-f</code> peut être
utilisé pour spécifier un autre nom de socket. Les modes de protection de
ce socket gère quels utilisateurs peut accéder aux fonctions APM.</li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<ul>
<li>
<p>apm(4), [[https://man.openbsd.org/apmd.8|apmd(8)]]</p>
</li>
<li>
<p>Advanced Power Management (APM) BIOS Interface Specification (revision 1.2),
Intel Corporation and Microsoft Corporation</p>
</li>
</ul>
<h3 id="histoire">Histoire</h3>
<p>La commande <strong>apm</strong> est apparue dans NetBSD 1.3 ; le support OpenBSD a
été ajoutée dans OpenBSD 1.2.</p>
<hr>
<p><em>Traduction ci-dessus du <a href="https://man.openbsd.org/apm.8" rel="external">manpage apm(8)</a> !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Gérer les modes d&#39;énergie et d&#39;hibernation sous OpenBSD, grâce au programme &#39;apm&#39;.]]></summary>
        <published>2016-12-10T16:30:49+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:bfa01346-4d76-43c9-b290-a2bad9b7a15b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/systat/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Systat : Voir la charge de la machine</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="systat" scheme="http://doc.huc.fr.eu.org/fr/tags/systat/" />
        <content type="html"><![CDATA[<h2 id="utilisation">Utilisation</h2>
<p>Quelques exemples :</p>
<p>⇒ charge réseau :</p>
<p><code>systat ifstat</code></p>
<p>⇒ charge système :</p>
<p><code>systat vm</code></p>
<figure>
    <a href="/images/openbsd/systatvm.png" title="Charge système avec systat vm">
    <picture>
        
        <source srcset="/images/openbsd/systatvm_hu_908ec95860b1b729.webp" type="image/webp">
        
        <img alt="Charge système avec systat vm" height="146" loading="lazy" src="/images/openbsd/systatvm_hu_938263a6287e575.png" type="image/png" width="200">
    </picture>
    </a>
    <figcaption>Charge système avec systat vm</figcaption>
</figure>
<p>⇒ pour les températures :</p>
<p><code>systat sensors</code></p>
<figure>
    <a href="/images/openbsd/systatsensors.png" title="Vérification des températures avec systat sensors">
    <picture>
        
        <source srcset="/images/openbsd/systatsensors_hu_ef6a308176e120a6.webp" type="image/webp">
        
        <img alt="Vérification des températures avec systat sensors" height="45" loading="lazy" src="/images/openbsd/systatsensors_hu_f0271f3c5d9e2a31.png" type="image/png" width="200">
    </picture>
    </a>
    <figcaption>Vérification des températures avec systat sensors</figcaption>
</figure>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="/fr/sys/openbsd/systat/#man-systat">man systat</a></li>
</ul>
<h3 id="man-systat">man systat</h3>
<h4 id="synopsis">Synopsis</h4>
<p><strong>systat</strong> [<strong>-aBbiNn</strong>] [<strong>-d</strong> count] [<strong>-s</strong> delay] [<strong>-w</strong> width] [view] [delay]</p>
<h4 id="description">Description</h4>
<p><strong>systat</strong> affiche nombre de statistiques systèmes, en fonction de l&rsquo;écran,
en utilisant la bibliothèque <a href="https://man.openbsd.org/curses" rel="external">curses(3)</a>.</p>
<p>Durant le fonctionnement de <strong>systat</strong>, l&rsquo;écran est divisé en plusieurs zones.</p>
<p>La première ligne en haut affiche le nombre actuel d&rsquo;utilisateurs, la
charge moyenne des trois systèmes (réel, virtuel, et mémoire) durant
l&rsquo;intervalle de la première minute, des 5 et 15 dernières minutes, et
l&rsquo;horloge système.</p>
<p>La ligne en bas de l&rsquo;écran est réservé aux entrées utilisateurs, et
messages d&rsquo;erreurs.</p>
<p>L&rsquo;information affichée dans le reste de l&rsquo;écran comprend une vue de
l&rsquo;activité système, et est l&rsquo;interface principale pour afficher les
différentes statistiques du système. La vue <code>vmstat</code> est celle par défaut.</p>
<p>Certaines informations peuvent ne pas être affichées si la taille de
l&rsquo;écran est insuffisante pour les afficher. Par exemple, sur une machine
avec 10 disques, la barre graphique d&rsquo;iostat affichera seulement 3
disques sur un terminal de 24 lignes.</p>
<p><strong>Pour connaître les options, lisez le <a href="https://man.openbsd.org/systat" rel="external">manpage</a> !</strong></p>
<h4 id="fichiers">Fichiers</h4>
<ul>
<li><code>/etc/hosts</code> : les noms de l&rsquo;hôte.</li>
<li><code>/etc/pf.conf</code> : la configuration de <a href="https://man.openbsd.org/pf.4" rel="external">pf(4)</a>.</li>
<li><code>/etc/services</code> : les noms des ports.</li>
</ul>
<h4 id="voir-aussi">Voir aussi</h4>
<p><a href="https://man.openbsd.org/fstat.1" rel="external">fstat(1)</a>, <a href="https://man.openbsd.org/kill.1" rel="external">kill(1)</a>, <a href="https://man.openbsd.org/netstat.1" rel="external">netstat(1)</a>, <a href="https://man.openbsd.org/nfsstat.1" rel="external">nfsstat(1)</a>, <a href="https://man.openbsd.org/ps.1" rel="external">ps(1)</a>, <a href="https://man.openbsd.org/top.1" rel="external">top(1)</a>, <a href="https://man.openbsd.org/iostat.8" rel="external">iostat(8)</a>, <a href="https://man.openbsd.org/pfctl.8" rel="external">pfctl(8)</a>, <a href="https://man.openbsd.org/pstat.8" rel="external">pstat(8)</a>, <a href="https://man.openbsd.org/renice.8" rel="external">renice(8)</a>, <a href="https://man.openbsd.org/sysctl.8" rel="external">sysctl(8)</a>, <a href="https://man.openbsd.org/vmstat.8" rel="external">vmstat(8)</a></p>
<h4 id="histoire">Histoire</h4>
<p>Le programme <strong>systat</strong> est apparu la première fois dans 4.3BSD.</p>
<h4 id="bogues">Bogues</h4>
<p>Certains affichages présument d&rsquo;un minimum de 80 caractères par ligne.
L&rsquo;affichage <code>vmstat</code> a ce problème (il a été ajouté en tant qu&rsquo;affichage
séparé, plutôt qu&rsquo;en tant que nouveau programme).</p>
<hr>
<p><em>Traduction du manpage <a href="https://man.openbsd.org/systat.1" rel="external">systat(1)</a> !</em></p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Statut système avec l&#39;outil &#39;systat&#39; sous OpenBSD]]></summary>
        <published>2016-12-10T16:30:10+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f964f3ef-70ae-c332-ea2b-73c13a089ce1</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/ntp-client/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: NTP Client : Heure locale synchronisée</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Network" scheme="http://doc.huc.fr.eu.org/fr/tags/network/" />
        <category term="NTP" scheme="http://doc.huc.fr.eu.org/fr/tags/ntp/" />
        <content type="html"><![CDATA[<h2 id="ntp-client--heure-locale-synchronisée">NTP Client : Heure locale synchronisée</h2>
<p>La synchronisation de l&rsquo;heure locale sous OpenBSD n&rsquo;est pas bien difficile.
Elle s&rsquo;effectue au-travers du projet <a href="http://www.openntpd.org/" rel="external">OpenNTPD</a>,
intégré nativement dans OpenBSD, et fonctionnel au démarrage de votre
ordinateur sous OpenBSD.</p>
<h3 id="serveurs-ntp">Serveurs NTP</h3>
<p>Les adresses de serveurs NTP sont visibles depuis la
<a href="http://support.ntp.org/bin/view/Servers/WebHome#Finding_A_Time_Server" rel="external">page pour trouver un serveur</a>.</p>
<p>Les <a href="http://support.ntp.org/bin/view/Servers/NTPPoolServers" rel="external">serveurs de pool NTP</a>
sont par zones mondiales comportant plusieurs pays.</p>
<ul>
<li>La zone Europe se gère à partir des serveurs <a href="http://www.pool.ntp.org/zone/europe" rel="external">europe.pool.ntp.org</a>.</li>
<li>La zone relative à la France est : <a href="http://www.pool.ntp.org/zone/fr" rel="external">fr.pool.ntp.org</a></li>
<li>etc…</li>
</ul>
<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration est <code>/etc/ntpd.conf</code>.</p>
<p>Pour qu&rsquo;il corresponde à l&rsquo;heure française, il faut modifier la ligne
correspondante à l&rsquo;option <code>servers</code>, telle que :</p>
<p><code>servers fr.pool.ntp.org</code></p>
<p>Pour en serveur NTP en local, utilisez plutôt - <em>à mettre en premier</em> -  :</p>
<p><code>server adr_ip_srvr</code></p>
<p><code>adr_ip_srvr</code> est bien sûr l&rsquo;adresse ip de votre serveur NTPD local ;
si vous avez une résolution DNS de celui-ci, vous pouvez spécifier le
nom d&rsquo;hôte !</p>
<h3 id="contraintes">Contraintes</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p><strong>À-propos des options de contraintes</strong> :<br>
ntpd(8) peut être configuré pour interroger la &lsquo;Date&rsquo; des serveurs HTTPS
de confiance via TLS. Cette information de temps n&rsquo;est pas utilisée pour
la précision mais agit comme une contrainte authentifiée, réduisant ainsi
l&rsquo;impact des attaques NTP non authentifiées de l&rsquo;homme au milieu.<br>
Les paquets NTP reçus dont les informations temporelles se situent en
dehors d&rsquo;une plage proche de la contrainte seront rejetés et ces serveurs
NTP seront marqués comme invalides.</p>
<hr>
<p>Dans ce <a href="https://marc.info/?l=openbsd-misc&amp;m=158888999317454&amp;w=2" rel="external">mail</a>,
Theo de Raadt explique pourquoi il n&rsquo;est pas désirable de personnaliser
les paramètres de contraintes autrement que ceux que l&rsquo;équipe fixe.<br>
Où l&rsquo;on apprend aussi que le domaine <strong><a href="https://www.openbsd.org" rel="external">www.openbsd.org</a></strong> ne doit pas être
invoqué, non plus…</p>
</div>

<h3 id="exemple">Exemple</h3>
<p>Exemple de configuration du fichier <code>/etc/examples/ntpd.conf</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># $OpenBSD: ntpd.conf,v 1.5 2019/11/11 16:44:37 deraadt Exp $</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sample ntpd configuration file, see ntpd.conf(5)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Addresses to listen on (ntpd does not listen by default)</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#listen on *</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># sync to a single server</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#server ntp.example.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a random selection of NTP Pool Time Servers</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># see http://support.ntp.org/bin/view/Servers/NTPPoolServers</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">servers pool.ntp.org</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># time server with excellent global adjacency</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">server time.cloudflare.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use a specific local timedelta sensor (radio clock, etc)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">sensor nmea0 trusted</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># use all detected timedelta sensors</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#sensor *</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># get the time constraint from a well-known HTTPS site</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraint from &#34;9.9.9.9&#34;		# quad9 v4 without DNS</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraint from &#34;2620:fe::fe&#34;		# quad9 v6 without DNS</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">constraints from &#34;www.google.com&#34;	# intentionally not 8.8.8.8</span>
</span></span></code></pre></div><h3 id="serveur-ntpd">Serveur NTPD</h3>
<p>⇒ <strong>OpenBSD ≥ 6.9</strong> : Il n&rsquo;est plus recommandé d&rsquo;activer le drapeau <code>-s</code>
pour gérer correctement les contraintes !</p>
<p>⇒ <strong>OpenBSD &lt; 6.9</strong> : Ensuite, il faut activer le drapeau <code>-s</code> pour que
le serveur ntpd essaye de modifier l&rsquo;heure locale, immédiatement au
moment du (re)démarrage du serveur.</p>
<p><code># rcctl set ntpd flags -s</code></p>
<h2 id="lheure-svp-">L&rsquo;heure, svp !</h2>
<p>Maintenant que la configuration est correctement faite, il nous faut
(re)démarrer le service <a href="http://man.openbsd.org/ntpd.8" rel="external">ntpd(8)</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># rcctl restart ntpd </span>
</span></span><span style="display:flex;"><span>ntpd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>ntpd<span style="color:#5bc4bf">(</span>ok<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p><em>Toute modification du fichier de configuration nécessite le redémarrage
du service NTP !</em></p>
<hr>
<p>Attendre quelques secondes, et ensuite, vérifiez le status de <strong>ntpd</strong>,
avec l&rsquo;outil de contrôle <a href="http://man.openbsd.org/ntpctl.8" rel="external">ntpctl(8)</a> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ doas ntpctl -sa 
</span></span><span style="display:flex;"><span>5/5 peers valid, 0/1 sensors valid, constraint offset -2s, clock unsynced
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>peer
</span></span><span style="display:flex;"><span>   wt tl st  next  poll          offset       delay      jitter
</span></span><span style="display:flex;"><span>162.159.200.1 time.cloudflare.com
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">7</span>  <span style="color:#f99b15">3</span>    5s    9s         0.848ms    52.534ms     1.445ms
</span></span><span style="display:flex;"><span>195.154.226.102 from pool fr.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">8</span>  <span style="color:#f99b15">2</span>   28s   32s         5.421ms    48.736ms     1.627ms
</span></span><span style="display:flex;"><span>93.113.207.65 from pool fr.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">8</span>  <span style="color:#f99b15">2</span>   33s   34s         6.263ms    51.508ms     2.299ms
</span></span><span style="display:flex;"><span>51.15.175.180 from pool fr.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">8</span>  <span style="color:#f99b15">2</span>   31s   32s         5.530ms    49.960ms     2.917ms
</span></span><span style="display:flex;"><span>5.39.80.51 from pool fr.pool.ntp.org
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">7</span>  <span style="color:#f99b15">2</span>    4s    9s         9.524ms    52.748ms     3.335ms
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sensor
</span></span><span style="display:flex;"><span>   wt gd st  next  poll          offset  correction
</span></span><span style="display:flex;"><span>upd0  
</span></span><span style="display:flex;"><span>    <span style="color:#f99b15">1</span>  <span style="color:#f99b15">0</span>  <span style="color:#f99b15">0</span>   12s   15s         - sensor not valid -
</span></span></code></pre></div><p>Un coup d’œil pour vérifier l&rsquo;horloge, en mode graphique, ou en mode
console :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ date
</span></span><span style="display:flex;"><span>Thu Apr <span style="color:#f99b15">27</span> 12:29:51 CEST <span style="color:#f99b15">2023</span>
</span></span></code></pre></div><hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>le manpage (<em>en anglais</em>) : <a href="http://man.openbsd.org/ntpd.conf" rel="external">http://man.openbsd.org/ntpd.conf</a></li>
<li>un exemple en local : <code>/etc/examples/ntpd.conf</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Synchroniser l&#39;heure locale sous OpenBSD grâce au client OpenNTP]]></summary>
        <published>2016-12-10T16:30:00+02:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:a35ee503-cc60-45ab-1ac0-74928cc8cf2e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/thunderbird/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Thunderbird / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Thunderbird" scheme="http://doc.huc.fr.eu.org/fr/tags/thunderbird/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="http://www.mozilla.org/thunderbird/" rel="external">Mozilla Thunderbird</a></strong> est une
ré-écriture des composants de la suite mail de Mozilla. Son objectif est
d&rsquo;exploiter une grande partie des fonctionnalités existantes de ce produit
pour créer une application de messagerie autonome, simple et extensible.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installez</a>
 le
paquet <code>thunderbird</code></strong>.</p>
<h2 id="configuration">Configuration</h2>
<h3 id="anti-aliasing">Anti-aliasing</h3>
<p>Pour désactivez l&rsquo;anti-aliasing, paramétrez <code>GDK_USE_XFT=0</code> dans votre e
nvironnement.</p>
<h3 id="doh">DoH</h3>
<p>Cette option semble être disponible depuis la v68.1 !</p>
<p>Pour activer DNS-sur-HTTPS <em>(

















<span lang="en">DoH <em>(DNS-over-HTTPS)</em></span>





























































































)</em>, ouvrez les <a>préférences</a> :</p>
<ul>
<li>Menu &ldquo;Avancé&rdquo;</li>
<li>Onglet &ldquo;Réseau et espace disque&rdquo;</li>
<li>Cliquez sur le bouton [ <u>P</u>aramètres… ]</li>
<li>Déroulez jusqu&rsquo;à la case à cocher &ldquo;Activer DNS sur HTTPS&rdquo; ; cochez
la case !</li>
<li>Cliquez sur la liste déroulante &ldquo;<u>U</u>tiliser le fournisseur&rdquo; et
choisissez &ldquo;Personnalisé&rdquo;, puis suivez les conseils ci-dessous :</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Il semble préférable de modifier l&rsquo;URL proposée par défaut… retrouvez des
adresses de serveurs DNS gérant DoH, par exemple, sur :</p>
<ul>
<li><a href="https://doh.defaultroutes.de/#sec-5-3" rel="external">https://doh.defaultroutes.de/#sec-5-3</a></li>
<li><a href="https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers" rel="external">https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers</a></li>
</ul>
<p>Cette URL est paramétrable aussi par le biais de
l&rsquo;<a href="/fr/sys/openbsd/thunderbird/#aboutconfig">éditeur de configuration</a> ; cherchez puis
modifiez la valeur <code>network.trr.uri</code>.</p>
</div>

<hr>
<p>L&rsquo;<a href="/fr/sys/openbsd/thunderbird/#aboutconfig">éditeur de configuration</a> permet de modifier les valeurs des
Résolveurs Récursifs de Confiance - <em>(en anglais : 

































































































<span lang="en">TRR <em>(Trusted Recursive Resolvers)</em></span>













)</em> :</p>
<ul>
<li><code>network.trr.mode</code> :
<ul>
<li><code>0</code> : défaut, <code>off</code></li>
<li><code>1</code> : mode <code>race</code></li>
<li><code>2</code> : TRR en premier</li>
<li><code>3</code> : TRR seulement</li>
<li><code>4</code> : mode <code>shadow</code></li>
<li><code>5</code> : désactivé par choix.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="enigmail">Enigmail</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Depuis courant de l&rsquo;année 2021, Thunderbird intègre nativement
la fonctionnalité de chiffrement de mails ; ce module n&rsquo;est plus nécessaire</div>

<p>Installer Enigmail depuis le <a href="https://www.enigmail.net/index.php/en/download/download-enigmail" rel="external">site officiel</a>
ou en tant que module.</p>
<p>Enigmail fonctionne avec la version GPG2 - <code>/usr/local/bin/gpg2</code>, installé
dans la structure de base d&rsquo;OpenBSD.</p>
<p>Néanmoins, pour que cela fonctionne correctement, il faudra
<a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 les
paquets suivants : <strong><code>pinentry</code> <code>pinentry-gtk2</code></strong> <br>
<em>(ou <code>pinentry-gtk3</code> selon votre environnement graphique)</em>.</p>
<h3 id="langue-française">Langue Française</h3>
<p>Avec Thunderbird v68, sous OpenBSD 6.6, il est possible de changer en
choisissant le menu &ldquo;Préférences&rdquo; (<u>E</u>dit &gt; Prefere<u>n</u>ces),
onglet &lsquo;General&rsquo;, Language, puis cliquez sur la liste déroulante pour
ajouter une nouvelle langue.</p>
<p>Vous aurez une nouvelle fenêtre qui s&rsquo;affiche qui vous permettra d&rsquo;ajouter
&lsquo;French&rsquo; ; validez votre choix par l&rsquo;appui sur le bouton [ OK ].</p>
<p>Redémarrez Thunderbird, et voilà !</p>
<h4 id="paquet-supplémentaire">Paquet supplémentaire</h4>
<p>Sinon, essayer d&rsquo;<strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 le paquet : <code>thunderbird-i18n-fr</code></strong>.</p>
<h4 id="éditeur-de-configuration">Éditeur de configuration</h4>
<p>Vous pouvez aussi d&rsquo;essayer l&rsquo;<a href="/fr/sys/openbsd/thunderbird/#aboutconfig">éditeur de configuration</a> :</p>
<ul>
<li>puis, faites un clic-droit pour : Ne<u>w</u> &gt; <u>S</u>tring.</li>
<li>Écrivez alors <code>intl.locale.requested</code> et mettez la valeur <code>fr-FR</code>.</li>
</ul>
<h3 id="liens">Liens</h3>
<p>Si vous avez des problèmes pour ouvrir les liens dans les mails, en
premier arrêtez Thunderbird.</p>
<p>Ensuite, éditez votre fichier <code>~/.thunderbird/&lt;something&gt;.default/prefs.js</code>
pour ajouter ce qui suit :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#06b6ef">user_pref(&#34;network.protocol-handler.app.ftp&#34;, &#34;/usr/local/bin/firefox&#34;);</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">user_pref(&#34;network.protocol-handler.app.http&#34;, &#34;/usr/local/bin/firefox&#34;);</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">user_pref(&#34;network.protocol-handler.app.https&#34;, &#34;/usr/local/bin/firefox&#34;);</span>
</span></span></code></pre></div><p>Puis, relancez Thunderbird !</p>
<h3 id="plugins">Plugins</h3>
<p>Thunderbird cherche les plugins dans les répertoires <code>~/.mozilla/plugins</code>
et <code>/usr/local/lib/mozilla/plugins</code>.</p>
<p>Si la variable d&rsquo;environnement <code>MOZ_PLUGIN_PATH</code> est spécifiée, elle
remplacera l&rsquo;endroit de recherche.</p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="aboutconfig">about:config</h3>
<p>Il est possible de faire certaines modifications de la configuration de
Thunderbird, par le biais de l&rsquo;<strong>éditeur de configuration</strong> <code>about:config</code>.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>L&rsquo;édition de la configuration comporte des risques ; en effet, une
mauvaise configuration peut rendre instable ou empêcher le logiciel de
fonctionner.</p>
<p>Une fois la configuration modifiée, il est important de redémarrer le
logiciel !</p>
</div>

<h4 id="thunderbird-en-anglais">Thunderbird en Anglais</h4>
<ul>
<li>menu <strong><u>E</u>dit</strong> &gt; <strong>Prefere<u>n</u>ces</strong></li>
</ul>
<p>Dans la fenêtre <code>Thunderbird Preferences</code> :</p>
<ul>
<li>menu <code>Advanced</code></li>
<li>onglet <code>General</code></li>
<li>cliquez sur le bouton [ <u>C</u>onfig Editor ]</li>
</ul>
<p>Dans la fenêtre <code>about:config</code> :</p>
<ul>
<li>cliquez sur le bouton [ I accept the risk ]</li>
</ul>
<h4 id="thunderbird-en-français">Thunderbird en Français</h4>
<ul>
<li>menu <strong>Éditio<u>n</u> &gt; Préfére<u>n</u>ces</strong></li>
</ul>
<p>Dans la fenêtre <code>Préférences de Thunderbird</code> :</p>
<ul>
<li>menu <code>Avancé</code></li>
<li>onglet <code>Général</code></li>
<li>cliquez sur le bouton [ É<u>d</u>iteur de configuration… ]</li>
</ul>
<p>Dans la fenêtre <code>about:config</code> :</p>
<ul>
<li>cliquez sur le bouton [ J&rsquo;accepte les risques ]</li>
</ul>
<h3 id="débogage">Débogage</h3>
<p>Veuillez IMPÉRATIVEMENT lire le fichier pkg-readme pour savoir comment faire.
Tout rapport sans information correcte sera purement et simplement ignoré !</p>
<h3 id="en-cas-de-dysfonctionnement">En cas de dysfonctionnement</h3>
<p>Si vous rencontrez des problèmes étranges ou que Thunderbird refuse de
démarrer, essayer de le démarrer avec l&rsquo;usage de l&rsquo;option <code>-safe-mode</code>.</p>
<h3 id="caldav">CalDAV</h3>
<p>Il semble avoir un problème avec les versions 60.x de Thunderbird pour
pouvoir se connecter aux services CalDAV de Nextcloud.</p>
<p>⇒ Version utilisée sous OpenBSD 6.4 !</p>
<p>C&rsquo;est un <a href="https://www.thunderbird.net/en-US/thunderbird/60.0/releasenotes/#known-issues" rel="external">problème connu</a>
chez Mozilla.</p>
<p>Ouvrez l&rsquo;<a href="/fr/sys/openbsd/thunderbird/#aboutconfig">éditeur de configuration</a>, puis :</p>
<ul>
<li>dans la barre de recherche, écrivez : <code>network.cookie.same-site.enabled</code></li>
<li>et positionnez-la sur : <code>false</code></li>
</ul>
<h3 id="enigmail-1">Enigmail</h3>
<p>Sous OpenBSD v6.0, un bogue fait que gpg 1 n&rsquo;est pas installé|installable ;
faites un lien symbolique de <code>/usr/local/bin/gpg2</code> vers <code>/usr/local/bin/gpg</code> :</p>
<p><code># ln -sf /usr/local/bin/gpg2 /usr/local/bin/gpg</code></p>
<p>OpenBSD v6.1 ne connaît pas ce soucis.</p>
<h3 id="français">Français</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Au-delà de Thunderbird v 52, l&rsquo;installation de ces modules n&rsquo;est plus
fonctionnelle !</div>

<p>Vous devez/pouvez aussi installer le
<strong><a href="https://addons.mozilla.org/en-US/thunderbird/addon/fran%C3%A7ais-language-pack-thunder/?src=search" rel="external">pack Français</a></strong>
en tant qu&rsquo;addon.</p>
<p>Une fois téléchargé, ouvrez TB, puis le menu &ldquo;Addons&rdquo;, puis cliquez sur
l&rsquo;icône en forme de roue crantée (//alias préférences//) pour choisir le
menu &ldquo;Install addon from file…&rdquo;.</p>
<p>Une fois installé, redémarrez TB.</p>
<ul>
<li><strong>OpenBSD v6.2, 6.3</strong> : <strong><a href="https://addons.mozilla.org/en-US/thunderbird/addon/fran%C3%A7ais-language-pack-thunder/versions/52.0" rel="external">version 52</a></strong></li>
</ul>
<p>Vous pouvez aussi installer l&rsquo;outil supplémentaire
&ldquo;<strong><a href="https://addons.mozilla.org/en-US/thunderbird/addon/quick-locale-switcher-2/" rel="external">Quick Locale Switcher 2</a></strong>&quot;…
qui vous servira surtout à basculer d&rsquo;une langue à l&rsquo;autre, au besoin.</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>Le fichier pkg-readme : <code>/usr/local/share/doc/pkg-readmes/thunderbird</code></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le client mail Thunderbird sous OpenBSD]]></summary>
        <published>2016-12-10T15:59:26+02:00</published>
        <updated>2025-11-19T15:01:42+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:04f09119-7701-80aa-853f-206c775ffc4d</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/git/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Git</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="git" scheme="http://doc.huc.fr.eu.org/fr/tags/git/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong><a href="https://git-scm.com/" rel="external">GIT</a></strong> est un &ldquo;gestionnaire de contenu de répertoire&rdquo;
conçu pour gérer des projets massifs avec rapidité et efficacité,</p>
<p>GIT entre dans la catégorie des outils de gestion de code source distribués,
semblable à par exemple GNU Arch ou Monotone (ou, dans le monde commercial,
BitKeeper). Chaque répertoire de travail GIT est un référentiel à part
entière avec des capacités de suivi de révision complètes, ne dépendant
pas de l&rsquo;accès réseau à un serveur central.</p>
<h2 id="installation">Installation</h2>
<p><strong><a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">Installez</a>
 le
paquet <code>git</code></strong>.</p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pour pouvoir utiliser la fonction <code>git send-email</code>, et utiliser <code>smtp</code>,
<code>tls</code>, il vous faut installer aussi les packages suivants :</p>
<ul>
<li><code>p5-Net-SMTP-SSL</code></li>
<li><code>p5-Authen-SASL</code></li>
</ul></div>

<h2 id="configuration">Configuration</h2>
<p>Le fichier de configuration : <code>~/.gitconfig</code></p>
<p>Exemple minimaliste :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[user]</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">name</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">identifiant
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">	email = email@domain.com</span>
</span></span></code></pre></div><h3 id="signature">Signature</h3>
<p>Depuis la version 1.7.9 de Git, il est possible de signer les commits,
ce qui permet d&rsquo;assurer que vous êtes bien l&rsquo;auteur de ceux-ci.</p>
<p>Pour signer vos commits, il est nécessaire d&rsquo;avoir créé dans un premier
temps une clé GPG - <em>ce mémo ne vous montrera pas comment faire</em>… <br>
L&rsquo;outil GPG2 est fourni de base dans OpenBSD. Néanmoins, il vous faudra
créer un lien symbolique pour lui faire croire qu&rsquo;il utilise GPG, car Git
semble ne pas être capable de comprendre !</p>
<p>Vous devrez ensuite modifier votre fichier de configuration afin de rajouter
l&rsquo;option <code>signingkey</code> dans la partie de configuration [user], tel que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#815ba4">[user]</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">name</span> <span style="color:#5bc4bf">=</span> <span style="color:#48b685">identifiant
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">	email = email@domain.com
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">        signingkey = votre_id_gpg</span>
</span></span></code></pre></div><p>La commande pour signer :</p>
<ul>
<li>un commit : <code>git commit -a -S -m 'un ou plusieurs longs commentaires'</code></li>
<li>un tag : <code>git tag -s v1.5 -m 'mon tag signé'</code></li>
</ul>
<p><em>Pour en connaître plus sur le fonctionnement de
<a href="https://git-scm.com/book/fr/v2/Utilitaires-Git-Signer-votre-travail" rel="external">git et le fait de signer</a>,
veuillez lire la doc officielle…</em></p>
<h2 id="dépannage">Dépannage</h2>
<h3 id="error-cannot-run-gpg-no-such-file-or-directory">error: cannot run gpg: No such file or directory</h3>
<p>Vous avez le message d&rsquo;erreur suivant dans son ensemble :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>error: cannot run gpg: No such file or directory
</span></span><span style="display:flex;"><span>error: impossible de lancer gpg.
</span></span><span style="display:flex;"><span>fatal: échec de l<span style="color:#48b685">&#39;écriture de l&#39;</span>objet commit
</span></span></code></pre></div><p>L&rsquo;outil GPG n&rsquo;est pas trouvé ; normal sous OpenBSD, il n&rsquo;existe pas.
L&rsquo;astuce est de lier GPG au binaire GPG2 :</p>
<p><code># ln -sf /usr/local/bin/gpg2 /usr/local/bin/gpg</code></p>
<h3 id="gpg-échec-de-la-signature-inappropriate-ioctl-for-device">gpg: échec de la signature : Inappropriate ioctl for device</h3>
<p>Le message d&rsquo;erreur est le suivant :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>gpg: échec de la signature : Inappropriate ioctl <span style="color:#815ba4">for</span> device
</span></span><span style="display:flex;"><span>gpg: signing failed: Inappropriate ioctl <span style="color:#815ba4">for</span> device
</span></span><span style="display:flex;"><span>error: gpg n<span style="color:#48b685">&#39;a pas pu signer les données
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">fatal: échec de l&#39;</span>écriture de l<span style="color:#ef6155">&#39;</span>objet commit
</span></span></code></pre></div><p>Il vous manque les paquets suivants : <strong><code>pinentry</code> <code>pinentry-gtk2</code></strong> ou
<strong><code>pinentry-gtk3</code></strong> - veillez à les <a class="inside" href="/fr/sys/openbsd/pkg/#installer" title="Lien interne vers l&#39;article : 'OpenBSD : Gestion des paquets (outils pkg_*)'">installer</a>
 !</p>
<p><em>Pour info, il semble que ce soit lié au
<a href="https://bugs.gnupg.org/gnupg/issue2680" rel="external">bogue 2680</a>
relatif à la version 2.1x de GPG.</em></p>
<h2 id="documentation">Documentation</h2>
<p>N&rsquo;oubliez pas de <strong>lire le fichier <code>/usr/local/share/doc/pkg-readmes/git</code></strong> ! ;-)</p>
<p>⇒ Git :</p>
<ul>
<li>La <strong>documentation de référence</strong> : <a href="https://git-scm.com/book/fr/v2" rel="external">https://git-scm.com/book/fr/v2</a></li>
<li>Un <strong>petit <a href="https://rogerdudler.github.io/git-guide/index.fr.html" rel="external">guide git</a>
pour démarrer</strong></li>
</ul>
<p>⇒ GPG :</p>
<ul>
<li>
<p>Comment bien configuré GPG pour l&rsquo;utiliser correctement :
<a class="inside" href="/fr/sec/gpg/gpg-usage-securise/" title="Lien interne vers l&#39;article : 'GPG : Du bon usage sécurisé'">GPG : Du bon usage sécurisé</a></p>
</li>
<li>
<p>Un guide des
<a class="inside" href="/fr/sec/gpg/gpg-guide-bonnes-pratiques/" title="Lien interne vers l&#39;article : 'GPG : Guide bonnes pratiques (RSA)'">bonnes pratiques pour créer ses clés GPG</a>
…</p>
</li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le gestionnaire de version Git, sous OpenBSD]]></summary>
        <published>2016-12-10T13:54:10+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:ce52ce43-b376-4b52-ef00-9c22c07a9c6b</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/trunk/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Trunk : Bascule automatique d&#39;interfaces réseaux</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Trunk" scheme="http://doc.huc.fr.eu.org/fr/tags/trunk/" />
        <content type="html"><![CDATA[<h2 id="trunk--bascule-automatique-dinterfaces-réseaux">Trunk : Bascule automatique d&rsquo;interfaces réseaux</h2>
<p><em>(de l&rsquo;ethernet au wifi, et réciproquement)</em></p>
<p>Pour ne pas se compliquer la vie et laisser OpenBSD utiliser la connexion
disponible, c&rsquo;est à dire le filaire quand il est branché physiquement,
par câble RJ45 ou par le wifi le cas échéant, on peut procéder comme suit :</p>
<p>⇒ Création d&rsquo;un fichier <code>/etc/hostname.re0</code> (où <code>re0</code> est l&rsquo;interface ethernet) :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ cat /etc/hostname.re0
</span></span><span style="display:flex;"><span>up
</span></span></code></pre></div><p>⇒ Création d&rsquo;un fichier <code>/etc/hostname.rtwn0</code> (<code>rtwn0</code> est l&rsquo;interface wifi) :</p>
<pre tabindex="0"><code>$ cat /etc/hostname.rtwn0
up
nwid kamehameha wpakey xxxxxxxxxxxxxxx
</code></pre><p>⇒ Et enfin, création d&rsquo;un fichier <code>/etc/hostname.trunk0</code> qui permet de
basculer sur l&rsquo;interface disponible :</p>
<pre tabindex="0"><code>$ cat /etc/hostname.trunk0
trunkproto failover trunkport re0
trunkport rtwn0
dhcp
inet6 autoconf
</code></pre><p>ps : bien sûr, vous pouvez ajouter d&rsquo;autres interfaces si vous en disposez.</p>
<h2 id="documentation">Documentation</h2>
<ul>
<li><a href="https://chown.me/blog/de-la-haute-dispo-sur-mon-lappy.html" rel="external">source</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Basculer d&#39;une interface réseau (wifi, RJ45, etc) de manière automatique sous OpenBSD]]></summary>
        <published>2016-12-10T13:37:45+02:00</published>
        <updated>2023-05-09T21:52:03+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:fdd15ab2-2df4-3731-fd9f-76c131d3ce05</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tips/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Trucs et astuces pour OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Avez-vous lu le <a class="inside" href="/fr/sys/openbsd/kit-survie/" title="Lien interne vers l&#39;article : 'Kit de survie sous OpenBSD'">Kit de survie</a>

après votre installation et suivie l&rsquo;étape &ldquo;<a class="inside" href="/fr/sys/openbsd/after-install/" title="Lien interne vers l&#39;article : 'Que faire après l&#39;installation d’OpenBSD ?'">Que faire après l&#39;installation d’OpenBSD ?</a>&rdquo;</p>
<p>Si oui, c&rsquo;est bien… sinon, faites-le !</p>
<p>Alors, retrouvez ci-dessous, classés par thématique, les différents trucs
et astuces qui pourront vous aider à démarrer… :D</p>
<h2 id="gestion-système">Gestion Système</h2>
<ul>
<li>pourquoi pas en savoir plus sur <a class="inside" href="/fr/sys/openbsd/tip-pdksh/" title="Lien interne vers l&#39;article : 'KSH : Korn shell'">KSH : Korn shell</a>,
<ul>
<li><a class="inside" href="/fr/sys/openbsd/tip-checksum/" title="Lien interne vers l&#39;article : 'Créer une somme de contrôle sous OpenBSD'">Créer une somme de contrôle sous OpenBSD</a>,</li>
<li>voire <a class="inside" href="/fr/sys/openbsd/tip-alias/" title="Lien interne vers l&#39;article : 'Les alias / OpenBSD'">Les alias / OpenBSD</a>,</li>
</ul>
</li>
<li><a class="inside" href="/fr/sys/openbsd/tip-boot/" title="Lien interne vers l&#39;article : 'Gestion du boot / OpenBSD'">Gestion du boot / OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-cpu/" title="Lien interne vers l&#39;article : 'Informations CPU / OpenBSD'">Informations CPU / OpenBSD</a></li>
<li>
<ul>
<li><em>voire de l&rsquo;<a class="inside" href="/fr/sys/openbsd/tip-tray-volume/" title="Lien interne vers l&#39;article : 'Gestion de l&#39;icône de volume dans la barre de notifications sous OpenBSD'">icône de volume</a>

dans certains bureaux graphiques, très minimaliste…</em></li>
</ul>
</li>
<li><a class="inside" href="/fr/sys/openbsd/tip-group/" title="Lien interne vers l&#39;article : 'Gestion des Group(e)s Systèmes sur OpenBSD'">Gestion des Group(e)s Systèmes sur OpenBSD</a>  &amp;&amp; <a class="inside" href="/fr/sys/openbsd/tip-limits/" title="Lien interne vers l&#39;article : 'Gestion des Limit(e)s Systèmes / OpenBSD'">Gestion des Limit(e)s Systèmes / OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-fr-lang/" title="Lien interne vers l&#39;article : 'Configurer la langue Française / OpenBSD'">Configurer la langue Française / OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-session/" title="Lien interne vers l&#39;article : 'Gestion de la session utilisateur / OpenBSD'">Gestion de la session utilisateur / OpenBSD</a> &amp;&amp; <a class="inside" href="/fr/sys/openbsd/tip-terminal/" title="Lien interne vers l&#39;article : 'Gestion d&#39;un terminal ou d&#39;une console sous OpenBSD'">Gestion d&#39;un terminal ou d&#39;une console sous OpenBSD</a></li>
<li>Comment paramétrer vos <a class="inside" href="/fr/sys/openbsd/tip-themes/" title="Lien interne vers l&#39;article : 'Thèmes ; Polices ; Émoticônes / OpenBSD'">Thèmes ; Polices ; Émoticônes / OpenBSD</a></li>
<li>Comprendre <a class="inside" href="/fr/sys/openbsd/tip-ffs2/" title="Lien interne vers l&#39;article : 'FFS2 : Système de Fichiers v2 sous OpenBSD'">FFS2 : Système de Fichiers v2 sous OpenBSD</a>, <a class="inside" href="/fr/sys/openbsd/tip-python/" title="Lien interne vers l&#39;article : 'Python : Gestion de l&#39;environnement / OpenBSD'">Python : Gestion de l&#39;environnement / OpenBSD</a></li>
</ul>
<h2 id="gestion-matériel">Gestion Matériel</h2>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/tip-burn-cdrom/" title="Lien interne vers l&#39;article : 'Graver un CD sous OpenBSD'">Graver un CD sous OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-bluetooth/" title="Lien interne vers l&#39;article : 'OpenBSD et le Bluetooth'">OpenBSD et le Bluetooth</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-usb/" title="Lien interne vers l&#39;article : 'Gestion des clés USB / OpenBSD'">Gestion des clés USB / OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-webcam/" title="Lien interne vers l&#39;article : 'Webcam / OpenBSD'">Webcam / OpenBSD</a></li>
<li><a class="inside" href="/fr/sys/openbsd/tip-wifi/" title="Lien interne vers l&#39;article : 'Gestion du Wifi / OpenBSD'">Gestion du Wifi / OpenBSD</a></li>
</ul>
<h2 id="réseaux">Réseaux</h2>
<ul>
<li>
<a class="inside" href="/fr/sys/openbsd/tip-howto-dl/" title="Lien interne vers l&#39;article : 'Comment télécharger en ligne de commande sous OpenBSD'">Comment télécharger en ligne de commande sous OpenBSD</a>
</li>
<li>
<a class="inside" href="/fr/sys/openbsd/tip-relayd/" title="Lien interne vers l&#39;article : 'Astuces relayd (OpenBSD)'">Astuces relayd (OpenBSD)</a>
</li>
<li>
<p>Utiliser un serveur proche pour obtenir des paquets (France) : <a class="inside" href="/fr/sys/openbsd/installurl/" title="Lien interne vers l&#39;article : 'installurl : localisation du serveur miroir OpenBSD'">installurl : localisation du serveur miroir OpenBSD</a></p>
</li>
<li>
<p>Utiliser le résolveur DNS local : <a class="inside" href="/fr/sys/openbsd/unbound/" title="Lien interne vers l&#39;article : 'OpenBSD : utiliser Unbound'">OpenBSD : utiliser Unbound</a></p>
</li>
</ul>
<h2 id="dépannage">Dépannage</h2>
<ul>
<li><a class="inside" href="/fr/sys/openbsd/tip-depannage/" title="Lien interne vers l&#39;article : 'OpenBSD - Dépannage'">OpenBSD - Dépannage</a></li>
</ul>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Recensement de différents trucs et astuces pour mieux appréhender OpenBSD]]></summary>
        <published>2016-12-10T12:51:01+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:13199608-6dac-849d-c66d-a1dbbc0f96ae</id>
        <link href="http://doc.huc.fr.eu.org/fr/trad/comprendre-unix-en-10-minutes/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Comprendre Unix en 10 Minutes</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Traduction" scheme="http://doc.huc.fr.eu.org/fr/tags/traduction/" />
        <category term="Unix" scheme="http://doc.huc.fr.eu.org/fr/tags/unix/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Retrouvez ci-dessous la traduction EN → FR de l&rsquo;article
&ldquo;<strong><a href="https://web.archive.org/web/20071230095405/http://freeengineer.org/learnUNIXin10minutes.html" rel="external">Learn UNIX in 10 minutes</a></strong>&rdquo;,
écrit sur le site disparu &lsquo;Freeengineer.org&rsquo;.</p>
<hr>
<h1 id="comprendre-unix-en-10-minutes">Comprendre Unix en 10 Minutes</h1>
<h2 id="préface">Préface</h2>
<p>Le propos est d&rsquo;avoir une page contenant les commandes de bases pour
démarrer l&rsquo;usage d&rsquo;un shell UNIX.</p>
<p>Ce document est protégé par les droits d&rsquo;auteurs, et placé sous les
termes de la licence GNU/<a href="http://www.gnu.org/copyleft/fdl.html" rel="external">FDL</a>.</p>
<h2 id="répertoires">Répertoires</h2>
<p>Les chemins de répertoires et fichiers dans Unix utilisent le symbole
&lsquo;/&rsquo; (slash) pour séparer le nom des répertoires, dans le contexte du
chemin.</p>
<p>exemples:</p>
<ul>
<li>
<p><code>/</code>   répertoire racine</p>
</li>
<li>
<p><code>/usr</code>    répertoire usr (répertoire enfant de la racine)</p>
</li>
<li>
<p><code>/usr/STRIM100</code>   STRIM100 est un sous-répertoire de /usr</p>
</li>
</ul>
<h3 id="circuler-dans-le-système-de-fichiers">Circuler dans le système de fichiers</h3>
<ul>
<li>
<p><code>pwd</code> voir le nom du répertoire courant</p>
</li>
<li>
<p><code>cd</code>  Se rediriger vers votre répertoire utilisateur personnel</p>
</li>
<li>
<p><code>cd /usr/STRIM100</code>    Se diriger vers /usr/STRIM100.</p>
</li>
<li>
<p><code>cd INIT</code> Se diriger vers le répertoire INIT,  qui est un
sous-répertoire du répertoire courant.</p>
</li>
<li>
<p><code>cd ..</code>   Se diriger vers le répertoire parent du répertoire courant.</p>
</li>
<li>
<p><code>cd $STRMWORK</code>    Se diriger vers le répertoire renfermé dans la
variable d&rsquo;environnement &lsquo;STRMWORK&rsquo;.</p>
</li>
<li>
<p><code>cd ~bob</code> Se diriger vers le répertoire personnel de bob.</p>
</li>
</ul>
<h3 id="lister-le-contenu-dun-répertoire">Lister le contenu d&rsquo;un répertoire</h3>
<ul>
<li>
<p><code>ls</code>  liste un répertoire</p>
</li>
<li>
<p><code>ls -l</code>   liste un répertoire dans un format détaillé</p>
</li>
<li>
<p><code>ls -a</code>   liste le répertoire courant en affichant les fichiers cachés,
ceux-ci commencent par un &ldquo;.&rdquo;</p>
</li>
<li>
<p><code>ls -ld</code>     Liste tous les noms de fichiers et répertoires dans le
répertoire courant, utilisant un format détaillé. Sans l&rsquo;option &rsquo;d&rsquo;,
la commande &rsquo;ls&rsquo; listera le contenu des sous-répertoire du
répertoire courant. Avec, &rsquo;ls&rsquo; listera juste le nom des fichiers.</p>
</li>
</ul>
<p>Pour l&rsquo;exemple :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ ls -l 
</span></span><span style="display:flex;"><span>drwxr-xr-x   <span style="color:#f99b15">4</span> cliff    user      <span style="color:#f99b15">1024</span> Jun <span style="color:#f99b15">18</span> 09:40 WAITRON_EARNINGS
</span></span><span style="display:flex;"><span>-rw-r--r--    <span style="color:#f99b15">1</span> cliff    user      <span style="color:#f99b15">767392</span> Jun <span style="color:#f99b15">6</span> 14:28 scanlib.tar.gz
</span></span><span style="display:flex;"><span>^^  ^  ^      ^ ^        ^         ^      ^     ^      ^
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>  |  |      | |        |         |      |     |      |
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>  |  |      | |id      |group    |poids |date |heure |nom 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>  |  |      |nombre de contenu 
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>  |  |permissions pour les autres
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>  |permissions pour les membres du groupe
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">||</span>permission pour le propriétaire du fichier : <span style="color:#ef6155">r</span> <span style="color:#5bc4bf">=</span> lecture, <span style="color:#ef6155">w</span> <span style="color:#5bc4bf">=</span> écriture, <span style="color:#ef6155">x</span> <span style="color:#5bc4bf">=</span> éxecution, - <span style="color:#5bc4bf">=</span> pas de permission
</span></span><span style="display:flex;"><span>|type de fichier : - <span style="color:#5bc4bf">=</span> fichier normal, <span style="color:#ef6155">d</span> <span style="color:#5bc4bf">=</span> répertoire, <span style="color:#ef6155">l</span> <span style="color:#5bc4bf">=</span> lien symbolique, etc…
</span></span></code></pre></div><h3 id="changer-les-permissions-et-attributs-de-fichiers">Changer les permissions et attributs de fichiers</h3>
<ul>
<li>
<p><code>chmod 755 file</code> Change les permissions du fichiers, en donnant tous
les droits au propriétaire du fichier, et les droits de lecture et
d&rsquo;exécution pour le groupe et les autres.
(7 = rwx = 111 en binaire ; 5 = r-x = 101 en binaire)</p>
</li>
<li>
<p><code>chgrp user file</code>  Change l&rsquo;appartenance du groupe sur le fichier.</p>
</li>
<li>
<p><code>chown cliff file</code>  Change le propriétaire du fichier.</p>
</li>
<li>
<p><code>chown -R cliff dir</code> Change le propriétaire du répertoire, de manière
récursive.</p>
</li>
</ul>
<p>Vous devez être le propriétaire des fichiers ou répertoires, ou être en
mode administrateur (root) avant de pouvoir interagir ainsi.</p>
<h3 id="déplacer-renommer-et-copier-des-fichiers">Déplacer, renommer, et copier des fichiers</h3>
<ul>
<li>
<p><code>cp file1 file2</code> Copier un fichier</p>
</li>
<li>
<p><code>mv file1 newname</code> Déplacer ou renommer un fichier</p>
</li>
<li>
<p><code>mv file1 ~/AAA/</code> Déplacer un fichier dans le sous-répertoire AAA de
votre répertoire utilisateur personnel</p>
</li>
<li>
<p><code>rm file1 [file2…]</code> Supprimer un fichier</p>
</li>
<li>
<p><code>rm -r dir1 [dir2…]</code> Supprimer un répertoire récursivement, et son
contenu. FAITES ATTENTION !</p>
</li>
<li>
<p><code>mkdir dir1 [dir2…]</code> Créer un répertoire</p>
</li>
<li>
<p><code>mkdir -p dirpath</code> Créer un répertoire, incluant tous les
sous-répertoires nommés en suivant</p>
</li>
<li>
<p><code>rmdir dir1 [dir2…]</code> Supprimer un répertoire vide</p>
</li>
</ul>
<h3 id="voir-le-contenu-et-éditer-des-fichiers">Voir le contenu et éditer des fichiers</h3>
<ul>
<li>
<p><code>cat filename</code> Afficher le contenu d&rsquo;un fichier à l&rsquo;écran, en ascii</p>
</li>
<li>
<p><code>more filename</code> Afficher le contenu d&rsquo;un fichier à l&rsquo;écran de manière
progressive. L&rsquo;appui sur la touche <kbd>Entrée</kbd> affiche la ligne
suivante ; celui sur la barre d&rsquo;<kbd>espace</kbd> affiche une nouvelle
page ; celui sur la touche <kbd>q</kbd> permettra la sortie.</p>
</li>
<li>
<p><code>less filename</code> Un peu comme &lsquo;more&rsquo;, mais permet l&rsquo;usage de la touche
<kbd>^</kbd> &ldquo;Défilement Haut&rdquo;, pour remonter les pages. Fonctionne
sur certains systèmes.</p>
</li>
<li>
<p><code>vi filename</code> Éditer le fichier en utilisant l&rsquo;éditeur &lsquo;vi&rsquo;.
Tous les systèmes Unix ont cet éditeur.</p>
</li>
<li>
<p><code>emacs filename</code> Éditer le fichier en utilisant l&rsquo;éditeur &rsquo;emacs&rsquo;.
Tous les systèmes Unix n&rsquo;ont pas cet éditeur.</p>
</li>
<li>
<p><code>head filename</code> Lire les premières lignes d&rsquo;un fichier.</p>
</li>
<li>
<p><code>head -n x filename</code> Lire les x premières lignes d&rsquo;un fichier</p>
</li>
<li>
<p><code>tail filename</code>  Lire les dernières lignes d&rsquo;un fichier</p>
</li>
<li>
<p><code>tail -n x filename</code>  Lire les x dernières lignes d&rsquo;un fichier</p>
</li>
</ul>
<h2 id="shells">Shells</h2>
<p>Le comportement d&rsquo;une interface de ligne de commande diffère étroitement
du programme shell dans lequel il est utilisée.</p>
<p>Dépendant du shell utilisé, quelques comportements supplémentaires
peuvent être utiles.</p>
<p>Il est possible de savoir sous quel shell vous fonctionnez, en utilisant
la commande suivante :</p>
<p><code>$ echo $SHELL</code></p>
<p>Bien-sûr, vous pouvez créer un fichier ayant une liste de commandes shell,
l&rsquo;exécuter tel un programme. Ceci est appelé un script shell. C&rsquo;est le
but premier de la plupart des shells.</p>
<h3 id="variables-denvironnement">Variables d&rsquo;environnement</h3>
<p>Les variables d&rsquo;environnement permettent au shell d&rsquo;enregistrer des
données, pour un usage ultérieur.</p>
<p>Par exemple, pour le shell nommé Bash :</p>
<ul>
<li>
<p><code>export CASROOT=/usr/local/CAS3.0</code>    Définit la variable CASROOT avec
la valeur /usr/local/CAS3.0.</p>
</li>
<li>
<p><code>export LD_LIBRARY_PATH=$CASROOT/Linux/lib</code>   Définit la variable
<code>LD_LIBRARY_PATH</code> avec la valeur de la variable <code>$CASROOT</code> concaténé
avec <code>/Linux/lib</code>, ou <code>/usr/local/CAS3.0/Linux/lib</code></p>
</li>
</ul>
<p>En préfixant la variable du symbole &lsquo;$&rsquo;, vous pouvez utiliser son
contenu dans le contexte de toute commande :</p>
<ul>
<li>
<p><code>cd $CASROOT</code>     Se rediriger vers le répertoire contenu dans la
variable <code>CASROOT</code></p>
</li>
<li>
<p><code>echo $CASROOT</code>   Afficher le contenu de la variable CASROOT,
soit <code>/usr/local/CAS3.0</code></p>
</li>
<li>
<p><code>printenv CASROOT</code>    Faire la même chose dans le shell bash ou
d&rsquo;autres environnements.</p>
</li>
</ul>
<h3 id="historique-interactif">Historique interactif</h3>
<p>Une fonctionnalité des shells bash, tcsh (et certainement d&rsquo;autres) est
de pouvoir utiliser l&rsquo;accès aux commandes précédentes par l&rsquo;appui de la
touche <kbd>^</kbd> &ldquo;Flèche Haut&rdquo;, de les éditer, et/ou de les exécuter
à nouveau.</p>
<p>Certains shells proposent l&rsquo;usage de la commande <code>history</code>, qui
affichera l&rsquo;ensemble des commandes utilisées.
Pour les réutiliser, si besoin, il suffit de précéder le numéro de la
commande du symbole <code>!</code>.</p>
<h3 id="complétion-de-nom-de-fichier">Complétion de nom de fichier</h3>
<p>Une fonctionnalité des shells bash, tcsh (et certainement d&rsquo;autres) est
de pouvoir utiliser la touche de Tabulation pour compléter un nom de
fichier partiellement tapé. Par exemple, si vous avez un fichier nommé
èconstantine-monks-and-willy-wonka.txt&rsquo; dans votre répertoire et que
vous désirez l&rsquo;éditer, vous pouvez écrire <code>vi const</code>, appuyez sur la
touche <kbd>Tab</kbd>, et le shell remplira le reste du nom de fichier.</p>
<h3 id="bash-est-le-shell-le-plus-cool">Bash est le shell le plus cool</h3>
<p>Bash est même capable de compléter le nom des commandes et des variables
d&rsquo;environnement. S&rsquo;il y a plusieurs complétions possibles, l&rsquo;appui
plusieurs fois sur la touche <kbd>Tab</kbd> vous affichera les
différentes possibilités.</p>
<p>Bash est le shell par défaut pour les systèmes Linux.</p>
<h3 id="redirection">Redirection</h3>
<ul>
<li>
<p><code>grep string filename &gt; newfile</code> Redirige la sortie de la commande
grep vers un nouveau fichier</p>
</li>
<li>
<p><code>grep string filename &gt;&gt; existfile</code> Ajoute la sortie de la commande
grep à la fin du fichier <code>existfile</code>.</p>
</li>
</ul>
<p>Les directives de redirection <code>&gt;</code> et <code>&gt;&gt;</code> peuvent être utilisées pour
diriger la sortie de la plupart des commandes vers un fichier.</p>
<h3 id="pipes">Pipes</h3>
<p>Le symbole <code>|</code> <em>(la barre vertical sous le chiffre 6 ; appuyer
simultanément sur les touches <kbd>Alt Gr</kbd> et <kbd>6</kbd>)</em> est
utilisé pour diriger la sortie d&rsquo;une commande vers l&rsquo;entrée d&rsquo;une autre
commande.</p>
<p>Par exemple :</p>
<ul>
<li>
<p><code>ls -l | more</code> Cette commande prend la sortie de la commande <code>ls</code> dans
son format détaillé et l&rsquo;affiche au-travers de la commande &lsquo;more&rsquo;.
Cela permet dans le cas d&rsquo;une très longue liste d&rsquo;être affichée page
par page.</p>
</li>
<li>
<p><code>du -sc * | sort -n | tail</code> La commande <code>du -sc</code> liste les tailles des
fichiers et répertoires, dans le répertoire de travail courant, puis
trie le résultat de la plus petite à la plus grosse grâce à la
commande <code>sort -n</code>. Finalement, seront affichés les quelques
derniers résultats, les plus gros fichiers, par le biais de la
commande <code>tail</code>.</p>
</li>
</ul>
<h3 id="substitution-de-commande">Substitution de commande</h3>
<p>Vous pouvez utiliser la sortie d&rsquo;une commande comme entrée d&rsquo;une autre
commande d&rsquo;une autre manière, appelée &ldquo;Substitution de commande&rdquo;. Elle
est invoquée par l&rsquo;usage du symbole `
<em>(appui simultané des touches <kbd>Alt Gr</kbd> et <kbd>7</kbd>)</em>,
tel que, pour l&rsquo;exemple :</p>
<p><code>$ cat `find . -name aaa.txt`</code></p>
<p>Ce qui affichera à l&rsquo;écran tous les fichiers nommés <code>aaa.txt</code> dans le
répertoire courant, et de ses sous-répertoires.</p>
<p>Actuellement, il est recommandé de l&rsquo;écrire ainsi :</p>
<p><code>$ cat &quot;$(find . -name aaa.txt)&quot;</code></p>
<h3 id="grep--recherche-de-chaînes-de-caractères-dans-un-fichier">grep : Recherche de chaînes de caractères dans un fichier</h3>
<ul>
<li><code>grep string filename</code>    affiche toutes les lignes contenant la
chaine <code>string</code> dans tel nom de fichier.</li>
</ul>
<h3 id="find--recherche-de-fichiers">find : Recherche de fichiers</h3>
<p><code>find search_path -name filename</code></p>
<ul>
<li>
<p><code>find . -name aaa.txt</code> Cherche tous les fichiers nommés <code>aaa.txt</code>
dans le répertoire courant et ses sous-répertoires.</p>
</li>
<li>
<p><code>find / -name vimrc</code>  Cherche tous les fichiers nommés <code>vimrc</code> partout
dans le système de fichiers.</p>
</li>
<li>
<p><code>find /usr/local/games -name &quot;*xpilot*&quot;</code> Cherche tous les fichiers
containant la chaîne <code>xpilot</code> dans leurs noms, qui existent dans le
répertoire <code>/usr/local/games</code>.</p>
</li>
</ul>
<h3 id="tar--lire-écrire-des-sauvegardes-et-autres-archives">tar : Lire, écrire des sauvegardes et autres archives</h3>
<p>La commande &rsquo;tar&rsquo; signifie &ldquo;tape archive&rdquo;. C&rsquo;est la manière &ldquo;standard&rdquo;
de lire et d&rsquo;écrire des archives <em>(qui sont des collections de fichiers,
dans un répertoire donné)</em>.</p>
<p>Vous trouverez souvent des archives avec des noms tels que <code>stuff.tar</code>,
ou <code>stuff.tar.gz</code>. En substance, cela signifie que le répertoire <code>stuff</code>
a été archivé dans une archive tar, et pour le second cas, que cette
archive a été compressée par le moyen du programme de compression <code>gzip</code>.</p>
<p>Il y a de fortes probabilités que si quelqu&rsquo;un vous donne une sauvegarde,
faite sur un système Unix, que cette sauvegarde soit faite dans le
format tar… et, dans ce cas, vous devrez utiliser <code>tar</code>, et votre lecteur
de bande, pour la lire.</p>
<p>De même, si vous voulez écrire une bande de sauvegarde pour quelqu&rsquo;un
d&rsquo;autre, vous devriez utiliser probablement tar, aussi.</p>
<p>Exemples :</p>
<ul>
<li>
<p><code>tar xv</code> Extrait les fichiers depuis la sauvegarde, en affichant le
nom des fichiers à l&rsquo;écran.  (<code>v</code> = verbeux)</p>
</li>
<li>
<p><code>tar tv</code> Liste les fichiers depuis la sauvegarde sans les extraire.</p>
</li>
<li>
<p><code>tar cv file1 file2</code> Écrit les fichiers <code>file1</code> et <code>file2</code> dans la
sauvegarde.</p>
</li>
<li>
<p><code>tar cvf archive.tar file1 [file2…]</code> Créer une archive tar, nommée
<code>archive.tar</code>, contenant les fichiers <code>file1</code>, <code>file2</code>, etc…
<em>Ne pas utilisez les symboles <code>[</code>, <code>]</code> : c&rsquo;est juste une convention
d&rsquo;écriture pour signifier l&rsquo;option…</em></p>
</li>
<li>
<p><code>tar xvf archive.tar</code> Extrait les fichiers de l&rsquo;archive <code>archive.tar</code></p>
</li>
<li>
<p><code>tar cvfz archive.tar.gz dname</code> Créer une archive compressée par gzip,
contenant tout le contenu du répertoire <code>dname</code>.
<em>Ne fonctionne pas avec toutes les versions de tar</em>.</p>
</li>
<li>
<p><code>tar xvfz archive.tar.gz</code> Extrait une archive compressée avec gzip.
<em>Ne fonctionne pas avec toutes les versions de tar</em>.</p>
</li>
<li>
<p><code>tar cvfI archive.tar.bz2 dname</code> Créer une archive tar compressée avec
le programme de compression bzip2.
<em>Ne fonctionne pas avec toutes les versions de tar</em>.</p>
</li>
</ul>
<h3 id="compression-de-fichiers">Compression de fichiers</h3>
<h4 id="compress">compress</h4>
<p>Les commandes de compression Unix, par défaut, sont <code>compress</code> et
<code>uncompress</code>. Les fichiers compressés ont le suffixe <code>.Z</code> ajouté à leur
nom.</p>
<p>Pour l&rsquo;exemple :</p>
<ul>
<li>
<p><code>compress part.igs</code> Créer un fichier compressé part.igs.Z</p>
</li>
<li>
<p><code>uncompress part.igs</code> Décompresser le contenu du fichier part.igs.Z</p>
</li>
</ul>
<p>Note que l&rsquo;usage de <code>.Z</code> n&rsquo;est pas requis.</p>
<h4 id="gzip">gzip</h4>
<p>Un autre utilitaire de compression commun est <code>gzip</code> (et <code>gunzip</code>). Ce
sont des outils GNU de compression et décompression. gzip utilise un
meilleur format de compression que le standard compress, mais n&rsquo;est pas
installé sur tous les systèmes. Le suffixe pour les fichiers compressés
par gzip est <code>.gz</code></p>
<ul>
<li>
<p><code>gzip part.igs</code> Créer un fichier compressé part.igs.gz</p>
</li>
<li>
<p><code>gunzip part.igs</code> Extrait le contenu de l&rsquo;archive part.igs.gz</p>
</li>
</ul>
<h4 id="bzip2">bzip2</h4>
<p>L&rsquo;utilitaire bzip2 a (en général) un meilleur taux de compression que
gzip, mais prend plus de temps pour compresser ou décompresser des
fichiers. Ce n&rsquo;est pas un utilitaire commun comme gzip, mais il devient
de plus en plus disponible.
<em>(À ce jour de la traduction, c&rsquo;est devenu un outil commun !)</em></p>
<ul>
<li>
<p><code>bzip2 part.igs</code> Créer un fichier compressé part.igs.bz2</p>
</li>
<li>
<p><code>bunzip2 part.igs.bz2</code> Décompresse le contenu du fichier part.igs.bz2</p>
</li>
</ul>
<h3 id="man-apropos--rechercher-de-laide-dans-le-système">man, apropos : Rechercher de l&rsquo;aide dans le système</h3>
<p>La plupart des commandes ont une page de manuel qui décrit comment
l&rsquo;utiliser, de manière plus ou moins détaillée. Ces pages de manuels
sont appelés des <code>man pages</code> parce qu&rsquo;elles sont faites pour être lues
par des humains.</p>
<p>Exemple :</p>
<ul>
<li><code>man ls</code>  Lire le manuel de la commande <code>ls</code>.</li>
</ul>
<p>Vous pouvez trouver les man pages en utilisant la commande <code>apropos</code>.</p>
<p>Exemple :</p>
<ul>
<li><code>apropos build</code> Afficher tous les man pages dont la description
contient le mot <code>build</code>.</li>
</ul>
<p>Pour l&rsquo;exemple, exécuter donc un <code>man apropos</code> pour obtenir l&rsquo;aide
détaillé de la commande <code>apropos</code>.</p>
<h2 id="bases-de-léditeur-vi">Bases de l&rsquo;éditeur <code>vi</code></h2>
<h3 id="ouvrir-un-fichier">Ouvrir un fichier</h3>
<ul>
<li><code>vi nom_fichier</code></li>
</ul>
<h3 id="créer-du-texte">Créer du texte</h3>
<p>Les modes d&rsquo;édition : l&rsquo;appui sur les touches ci-dessous permettent
d&rsquo;entrer en mode édition, puis d&rsquo;écrire le contenu de votre document.</p>
<ul>
<li>
<p><code>i</code> Insérer des caractères avant la position du curseur.</p>
</li>
<li>
<p><code>I</code> Insérer des caractères au début de la ligne courante.</p>
</li>
<li>
<p><code>a</code> Ajouter après la position du curseur.</p>
</li>
<li>
<p><code>A</code> Ajouter à la fin de la ligne courante.</p>
</li>
<li>
<p><code>r</code> Remplacer un caractère.</p>
</li>
<li>
<p><code>R</code> Mode remplacement</p>
</li>
<li>
<p><code>&lt;ESC&gt;</code> Sort des modes insertion.</p>
</li>
</ul>
<h3 id="suppression-de-texte">Suppression de texte</h3>
<ul>
<li>
<p><code>x</code> Supprime un caractère</p>
</li>
<li>
<p><code>dd</code> Supprime la ligne courante et la met en mémoire-tampon</p>
</li>
<li>
<p><code>ndd</code> Supprime n lignes (n étant un nombre) et les mets dans la
mémoire-tampon.</p>
</li>
<li>
<p><code>J</code> Attache une nouvelle ligne à la fin de la ligne courante (et
supprime les caractères de retour-à-la ligne)</p>
</li>
</ul>
<h3 id="oups--erreur-de-saisie">Oups : Erreur de saisie</h3>
<ul>
<li><code>u</code> Annule la dernière commande</li>
</ul>
<h3 id="copier-coller">Copier, Coller</h3>
<ul>
<li>
<p><code>yy</code> Copie la ligne courante dans la mémoire-tampon</p>
</li>
<li>
<p><code>nyy</code> Copie n lignes dans la mémoire-tamon</p>
</li>
<li>
<p><code>p</code> Colle le contenu de la mémoire-tampon après la ligne courante</p>
</li>
<li>
<p><code>P</code> Colle le contenu de la mémoire-tampon avant la ligne courante</p>
</li>
</ul>
<h3 id="positionner-le-curseur">Positionner le curseur</h3>
<p>Le symbole <code>^</code> signifie l&rsquo;appui simultanée sur la touche <kbd>Ctrl</kbd>
puis la touche signalée !</p>
<ul>
<li>
<p><code>^d</code> Descend d&rsquo;une page</p>
</li>
<li>
<p><code>^u</code> Remonte d&rsquo;une page</p>
</li>
<li>
<p><code>:n</code> Positionne le curseur à la ligne n</p>
</li>
<li>
<p><code>:$</code> Positionne le curseur à la fin de la ligne courante</p>
</li>
<li>
<p><code>^g</code> Affiche le numéro de la ligne courante</p>
</li>
<li>
<p><code>h,j,k,l</code> Respectivement, à gauche, en bas, au-dessus, et à droite du
curseur. Vous pouvez aussi utiliser les touches fléchées si cela
fonctionne avec votre clavier.</p>
</li>
</ul>
<h3 id="remplacement-de-caractères">Remplacement de caractères</h3>
<p><code>:n1,n2:s/string1/string2/[g]</code> Remplace la chaîne de caractères 1 par la
chaine de caractères 2 sur les lignes n1 et n2. Quand <code>g</code> est inclus
(pour global), toutes les instances de la chaînes de caractère 1 sur
chacunes des lignes sont remplacées. Si <code>g</code> n&rsquo;est pas inclus, seule
la première instance par ligne correspondante est remplacée.</p>
<ul>
<li>
<p><code>^</code> correspond au début de ligne.</p>
</li>
<li>
<p><code>.</code> signifie tout caractère</p>
</li>
<li>
<p><code>$</code> correspond à la fin de ligne.</p>
</li>
</ul>
<p>Ces caractères, ainsi que d&rsquo;autres &ldquo;caractères spéciaux&rdquo; (tels que
l&rsquo;anti-slash) peuvent être échappés par l&rsquo;usage du symbole <kbd>\</kbd>,
tel que <code>\/usr\/STRIM100\/SOFT</code> signifiant littéralement la chaîne de
caractère <code>/usr/STRIM100/SOFT</code></p>
<p>Exemples :</p>
<ul>
<li><code>:1,$:s/dog/cat/g</code> Remplacer chaque instance <code>dog</code> par <code>cat</code>, dans
tout le fichier. <em>L&rsquo;usage de <code>:1,$</code> signifie du début à la fin du
fichier</em>.</li>
<li><code>:23,25:/frog/bird/</code> Sur les lignes 23 à 25, remplacer la première
instance de <code>frog</code> par <code>bird</code>, dans chacune de ces lignes.</li>
</ul>
<h3 id="sauver-quitter-et-autres-commandes-ex">Sauver, quitter et autres commandes <code>ex</code></h3>
<p>Ces commandes sont toutes préfixées par l&rsquo;usage du symbole <kbd>:</kbd>,
et affichées en bas, à gauche de l&rsquo;écran. Ce sont les commandes <code>ex</code>,
parce qu&rsquo;elles font partie de l&rsquo;éditeur de texte <code>ex</code>, le précurseur de
l&rsquo;éditeur de texte <code>vi</code>.
Vous ne pouvez pas taper une commande <code>ex</code> quand vous êtes dans un des
modes insertion. (la saisie de texte à l&rsquo;écran). Pour pouvoir le faire,
il faut appuyer sur la touche <kbd>ESC</kbd>, qui vous fera sortir de ce
mode d&rsquo;insertion.</p>
<ul>
<li>
<p><code>:w</code>  Sauvegarde le fichier courant</p>
</li>
<li>
<p><code>:w new.file</code> Sauvegarde le fichier courant, dans un nouveau fichier</p>
</li>
<li>
<p><code>:w! existing.file</code>   Sauvegarde un fichier existant avec le contenu
du fichier courant.</p>
</li>
<li>
<p><code>:wq</code> Sauvergarde le fichier et sors de l&rsquo;éditeur</p>
</li>
<li>
<p><code>:q</code>  Ferme l&rsquo;éditeur</p>
</li>
<li>
<p><code>:q!</code> Ferme l&rsquo;éditeur sans faire de changement</p>
</li>
<li>
<p><code>:e filename</code> Ouvre le fichier &lsquo;filename&rsquo; pour édition</p>
</li>
<li>
<p><code>:set number</code> Affiche le numéro de ligne</p>
</li>
<li>
<p><code>:set nonumber</code>   Éteint le numéro de ligne</p>
</li>
</ul>
<h2 id="faq">FAQ</h2>
<p>Le contenu des Foire-aux-Questions Usenet devraient être le premier
endroit à lire pour vos questions. Vous pouvez y trouver beaucoup de
manuel <a href="ftp://rtfm.mit.edu/pub/" rel="external">RTFM</a>
<em>(Read the F*** Manuals ; Lis ce Fichu Manuel)</em>.</p>
<p>Le contenu de ce <a href="ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/unix/questions/" rel="external">répertoire</a>
inclut les FAQs vi, bash, et comp.unix.questions.</p>
<p>Rechercher dans les archives Usenet est souvent très utile, aussi.</p>
<p>Google.com a sa propre archive Usenet (formellement Deja.com), voire les
règles &ldquo;Advanced Group Search&rdquo;.</p>
<hr>
<h2 id="mention-originale-traduite">Mention originale (traduite)</h2>
<p>Ce document <em>(comprendre l&rsquo;original ; ce n&rsquo;est pas le cas de la traduction)</em>
a été converti depuis un fichier texte, en utilisant Vim. Vim est la
meilleure version du seul vrai éditeur de texte : vi.</p>
<p>Copyright (c)  2000-2006 - <a href="mailto:cliff@freeenginer.org" rel="external">cliff@freeenginer.org</a></p>
<p>Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with
Invariant Section: Preface, with Front-Cover Texts, and with no
Back-Cover Texts. A copy of the license can be found on the GNU web site
<a href="http://www.gnu.org/copyleft/fdl.html" rel="external">here</a>.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette traduction sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Traduction EN → FR de l&#39;article &#39;Learn UNIX in 10 minutes&#39; du site disparu &#39;Freeengineer.org&#39;]]></summary>
        <published>2016-12-10T12:13:31+02:00</published>
        <updated>2023-05-10T16:56:33+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:15201a0a-46df-f7d2-4c76-61a4a9899d4e</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-alias/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Les alias / OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="Alias" scheme="http://doc.huc.fr.eu.org/fr/tags/alias/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Éditez votre fichier <code>~/.profile</code> !</p>
<h2 id="exemples">Exemples</h2>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">alias add</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pkg_add&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias del</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas pkg_del&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias enable</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas rcctl enable&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias query</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;pkg_info -Q&#34;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">alias ll</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;ls -lart&#34;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">alias restart</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas rcctl restart&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias start</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas rcctl start&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias stop</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;doas rcctl stop&#34;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># Alias</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Raccourcis pour &#39;ls&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias ll</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;ls -l&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias la</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;ls -a&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias lla</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;ls -la&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias lls</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;ls -s&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Quelques alias pratiques</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias cls</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;clear&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias less</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;less --quiet&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71">#Connaitre l&#39;espace restant</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias dh</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;df -h&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># kill&#39;em all</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias rmr</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;rm -rf&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias cpr</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;cp -r&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># noir et blanc, c&#39;est cool</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias xterm</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;xterm -bg black -fg white&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Remonter d&#39;un dossier et ls</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias u</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;cd .. &amp;&amp; ls &#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Edition simple</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias v</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;vim&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Voir le débit réseau</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias bw</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;systat ifstat&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># infos sur la charge de la machine</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias totop</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;systat vm&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># info ram/swap (free-like)</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias freemem</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;top -d1 | grep &#34;^Memory&#34; &amp;&amp; printf &#34;Swap:  &#34; ; swapctl -s&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Une calculatrice en python</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias calc</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;python3.4 -ic &#34;from math import *; from random import *&#34;&#39; </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># compare 2 répertoire</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias diffdir</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;diff -rq $1 $2&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># réduire le poids d&#39;un pdf</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pdfmini</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#34;gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=fichier_reduit.pdf &#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># adresse ip</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias whatsmyip</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;http_proxy=&#34;&#34; ftp -o - -V http://ipecho.net/plain &amp;&amp; echo &#34;&#34;&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias whatsmyip2</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;ftp -o - -V http://ifconfig.me/ip&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># Enlever les commentaires : </span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias nocomment</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;egrep -v &#34;^\s*(#|$)&#34;&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># insert image in latex slide</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias img2slide</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;mogrify -density 96 -units PixelsPerInch&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># easy pastebin</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias clbin</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;curl -v -F &#34;clbin=&lt;-&#34; https://clbin.com&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># serveur http simple</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias pyserver</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;python3.4 -m http.server&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># w3m et ses bookmarks</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias web</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;w3m -B&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># star wars</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias sw</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;telnet towel.blinkenlights.nl&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># quels ports sont ouverts ?</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias openports</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;netstat -na -f inet |grep LISTEN&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># trouver un processus en lien avec un port/ip/proto/etc.</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">openpid() {</span>
</span></span><span style="display:flex;"><span>	<span style="color:#06b6ef">fstat | egrep &#34;(^USER|$1)&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># take screenshot and upload. Save the URL in clipboard</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias shotup</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">&#39;scrot -s /tmp/shotup.png &amp;&amp; curl -F &#34;clbin=@/tmp/shotup.png&#34; https://clbin.com -selection clipboard&#39;</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment gérer les alias sous OpenBSD !]]></summary>
        <published>2016-12-10T12:12:58+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f9ed72ab-f92a-9601-3828-7e1ffc812626</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/tip-burn-cdrom/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Graver un CD sous OpenBSD</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="Astuce" scheme="http://doc.huc.fr.eu.org/fr/tags/astuce/" />
        <category term="CDRom" scheme="http://doc.huc.fr.eu.org/fr/tags/cdrom/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>La majeure partie de ce qui est écrit ici provient, comme d&rsquo;habitude, de
la <a href="https://www.openbsd.org/faq/faq13.html#burnCD" rel="external">documentation</a>.</p>
<p>Déjà, on commence par mettre tous les fichiers à graver dans un dossier
que j&rsquo;appelle ici &ldquo;cd&rdquo; par souci d&rsquo;originalité :) .</p>
<p>Vérifiez bien que les documents ne prennent pas trop de place.
Par exemple, j&rsquo;ai un CD de 700MB , je regarde avec la commande &ldquo;du&rdquo; si
ça passe :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ du -h cd
</span></span><span style="display:flex;"><span>472M	cd
</span></span></code></pre></div><p>C&rsquo;est bon :)</p>
<p>On fabrique maintenant un fichier <code>moncd.iso</code> que l&rsquo;on pourra graver :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ mkhybrid -R -o moncd.iso cd/
</span></span></code></pre></div><p>On vide le cd :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># cdio -f cd0c blank</span>
</span></span></code></pre></div><p>Et enfin, on grave l&rsquo;iso :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># cdio -f cd0c tao moncd.iso</span>
</span></span></code></pre></div><p>On peut vérifier que tout s&rsquo;est bien passé en montant le CD fraîchement
gravé :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># mount /dev/cd0c /mnt/cdrom</span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># ls /mnt/cdrom</span>
</span></span></code></pre></div><p><strong>ATTENTION</strong> : Pour les DVD, la démarche est légèrement différente.</p>
<hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation de manière collaborative
sur le wiki de la communauté &ldquo;OpenBSD Pour Tous&rdquo;.</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Astuce : comment graver un cdrom sous OpenBSD]]></summary>
        <published>2016-12-10T07:00:28+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:73290972-c01c-020a-8089-e79f17455311</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/openbsd/spamd/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Spamd</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="OpenBSD" scheme="http://doc.huc.fr.eu.org/fr/tags/openbsd/" />
        <category term="spamd" scheme="http://doc.huc.fr.eu.org/fr/tags/spamd/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p><strong>spamd</strong> fait semblant d&rsquo;être un serveur mail afin de rejeter les spams.
Il a été écrit dans l&rsquo;optique d&rsquo;être très efficace et ne pas ralentir la
machine.</p>
<p>Bien sûr, il transmet les mails légitimes au serveur smtp ensuite.</p>
<p>Ce qui est rigolo en plus, c&rsquo;est qu&rsquo;il va faire en sorte de ralentir les
spammeurs en communiquant tout doucement avec eux et leur faire consommer
inutilement leur ressources :) .</p>
<p>Enfin, avantage non négligeable, il est présent par défaut dans OpenBSD.</p>
<h3 id="comment-ça-marche">Comment ça marche?</h3>
<p>Afin de reconnaître les spam, spamd va mettre en attente ceux qui contactent
le serveur. Ils sont mis sur <strong>liste grise</strong>.</p>
<p>Normalement, un expéditeur légitime réessaie automatiquement de délivrer
le message.</p>
<p>Lors du 2e essai, ce serveur est mis sur <strong>liste blanche</strong>.</p>
<p>Les spammeurs ne vont pas réessayer de délivrer le message. Dans ce cas,
ils sont mis après un délai assez long sur <strong>liste noire</strong>. <br>
Par la suite, votre serveur n&rsquo;écoutera même plus les requêtes provenant
de ces spammeurs.</p>
<p>Afin d&rsquo;enregistrer les vilains expéditeurs, il faudra exécuter spamd<br>
régulièrement.</p>
<h2 id="utilisation">Utilisation</h2>
<p>On commence par activer spamd au démarrage, en indiquant les options dont
il aura besoin, puis on le lance :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>rcctl enable spamd
</span></span><span style="display:flex;"><span>rcctl set spamd flags <span style="color:#48b685">&#34;-v -G 15:4:4242&#34;</span>
</span></span><span style="display:flex;"><span>rcctl start spamd
</span></span></code></pre></div><ul>
<li>Le premier chiffre correspond au nombre de minutes qu&rsquo;un expéditeur doit
attendre avant de réessayer de nous renvoyer son mail (puisque les spammeurs
envoie des salves de mails très rapidement).</li>
<li>Le second correspond au temps qu&rsquo;une entrée reste dans la liste grise,</li>
<li>et le dernier le temps pendant lequel une entrée restera sur la liste
blanche (en heures).</li>
</ul>
<p>On va maintenant éditer la configuration du parefeu et filtre de paquets
(packet filter). Il va envoyer à spamd tous le flux destiné au serveur
smtp, qui relaiera normalement ensuite si le mail est légitime.</p>
<p>Voici ce qu&rsquo;il faut donc ajouter dans <code>/etc/pf.conf</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">table &lt;nospamd&gt; persist file &#34;/etc/mail/nospamd&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto tcp from any to any port smtp \</span>
</span></span><span style="display:flex;"><span>    <span style="color:#06b6ef">divert-to 127.0.0.1 port spamd</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in on egress proto tcp from &lt;nospamd&gt; to any port smtp</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">pass in log on egress proto tcp from &lt;spamd-white&gt; to any port smtp</span>
</span></span></code></pre></div><p>Dans l&rsquo;ordre des lignes :</p>
<ul>
<li>On crée un fichier <code>/etc/mail/nospamd</code> qui contiendra les expéditeurs légitimes</li>
<li>On dévie tout ce qui devait arriver sur le port smtp pour aller dans spamd</li>
<li>On laisse passer toutes les IP qui étaient dans le premier fichier</li>
<li>On laisse passer les IP enregistrée par spamd dans la liste blanche
(en mémoire). spamd et pf partagent ici la même table.</li>
</ul>
<p>Voilà pour le parefeu. N&rsquo;oubliez pas de le recharger :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># pfctl -d &amp;&amp; pfctl -ef /etc/pf.conf</span>
</span></span></code></pre></div><p>Il est nécessaire de régulièrement charger la liste noire des spammeurs
dans le parefeu afin que spamd fonctionne bien. Nous allons nous servir
d&rsquo;une tâche cron pour ça.</p>
<p>Éditez votre crontab puis ajoutez la ligne suivante :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">*/10      *       *       *       *       /usr/libexec/spamd-setup</span>
</span></span></code></pre></div><p>Nous lançons ici <code>spamd-setup</code> toutes les 10 minutes. Ce temps doit être
inférieur au temps que doit attendre un expéditeur pour tenter de renvoyer
son message définit dans l&rsquo;appel de spamd. Nous avions mis 15 minutes.</p>
<h3 id="piéger-les-spammeurs">Piéger les spammeurs</h3>
<p>Vous pouvez piéger les spammeurs en laissant traîner sur le web une fausse
adresse mail. Si spamd voit un message arriver pour cette adresse, alors
il sait déjà que c&rsquo;est un spam : il peut donc le mettre sur <strong>liste noire</strong>.</p>
<p>Vous voilà protégés pour l&rsquo;avenir.</p>
<p>Afin de glisser cette &ldquo;adresse-piège&rdquo; sur le web sans que ça soit visible
par les humain, vous pouvez l&rsquo;insérer ainsi dans une page web de votre site :</p>
<pre tabindex="0"><code>&lt;a href=&#34;mailto:blackhole@votre-nom-de-domaine.tld&#34;&gt;&lt;/a&gt;
</code></pre><p>Pour indiquer à spamdb cette adresse piège, il faut ajouter les options
suivantes à spamdb (attention au &ldquo;b&rdquo; final, ce n&rsquo;est pas spamd). :</p>
<pre tabindex="0"><code># spamdb -T -a &#39;blackhole@votre-nom-de-domaine.tld&#39;
</code></pre><p>Bien entendu, cette adresse piège ne doit pas être créée et ne risque pas
de servir à quiconque.</p>
<h3 id="status">Status</h3>
<p>Pour voir l&rsquo;activité de spamd, lancez la commande <code>spamdb</code> pour voir
apparaître des choses comme ça :</p>
<pre tabindex="0"><code class="language-log" data-lang="log">WHITE|62.4.1.33|||1462699174|1462699174|1465809574|1|0
GREY|46.105.39.61|2.mo178.mail-out.ovh.net|&lt;contact@arpinux.org&gt;|&lt;thuban@yeuxdelibad.net&gt;|1462696130|1462710530|1462710530|1|0
</code></pre><p>On peut lire dans l&rsquo;ordre :</p>
<ul>
<li>Si l&rsquo;IP est sur liste blanche (WHITE) ou grise (GREY)</li>
<li>L&rsquo;IP concernée</li>
<li>Temps où cette entrée a été vue la première fois</li>
<li>Le moment où l&rsquo;IP sera passée en liste blanche</li>
<li>Le moment où l&rsquo;IP sera retirée de la base de données</li>
<li>Le nombre de fois où cette IP a été bloquée</li>
<li>Le nombre de fois où ces IP a été autorisée.</li>
</ul>
<p>Il n&rsquo;y a pas à dire, les &ldquo;temps&rdquo; sont illisibles pour les humains.</p>
<p>Utiliser la commande <code>date</code> pour avoir un format lisible :</p>
<pre tabindex="0"><code>$ date -r 1462699174
    Sun May  8 11:19:34 CEST 2016
</code></pre><h3 id="accepter-une-ip-manuellement">Accepter une IP manuellement</h3>
<p>Si vous constatez des erreurs en tapant <code>spamdb</code>, vous pouvez autoriser
une IP ainsi :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#776e71"># spamdb -a 12.234.56.67</span>
</span></span></code></pre></div><hr>
<h2 id="historique">Historique</h2>
<p>J&rsquo;ai écrit historiquement cette documentation sur le wiki de la communauté
&ldquo;OpenBSD Pour Tous&rdquo;, (conjointement avec Xavier Catron).</p>
<hr>
]]></content>
        <summary type="html"><![CDATA[Utiliser le serveur d&#39;antispam, Spamd, sous OpenBSD]]></summary>
        <published>2016-09-03T12:40:46+02:00</published>
        <updated>2023-04-30T17:05:08+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:86530517-fbd0-6502-b314-3c7797fb2f19</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/unbound-dnssec-trigger/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Utiliser Unbound avec DNSSEC &#43; dnssec-trigger</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="unbound" scheme="http://doc.huc.fr.eu.org/fr/tags/unbound/" />
        <category term="dnssec-trigger" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec-trigger/" />
        <category term="DNSSEC" scheme="http://doc.huc.fr.eu.org/fr/tags/dnssec/" />
        <content type="html"><![CDATA[<h2 id="description">Description</h2>
<p>Le but d&rsquo;utiliser Unbound est d&rsquo;avoir localement sur sa station son propre
serveur DNS Cache (enregistrant la relation noms de domaine et adresses IP
déjà visités, afin de ne pas aller interroger les serveurs DNS Root, sauf
à changement de ladite information). Et, utiliser Unbound avec la gestion
sécurisée des informations DNS, par le biais de la technologie DNSSEC, est
un plus indéniable <em>(cela évite d&rsquo;avoir à obtenir des informations DNS faussées,
par une action pirate)</em>.</p>
<p>Cette dernière est assumée, en partie, par l&rsquo;outil <strong>dnssec-trigger</strong> !</p>
<h3 id="versions-utilisées">Versions utilisées</h3>
<ul>
<li>OS : Debian Stable / Sid</li>
<li>unbound : selon la version de Debian utilisée</li>
<li>dnssec-trigger : selon la version de Debian utilisée</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Avec Debian, comme d&rsquo;habitude, rien de bien compliqué !</p>
<p><code># apt install unbound unbound-host dnssec-trigger</code></p>
<p>Les fichiers de configuration principaux :</p>
<ul>
<li>d&rsquo;unbound sont dans <code>/etc/unbound/</code> ;</li>
<li>ceux de dnssec-trigger dans <code>/etc/dnssec-trigger/</code></li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Préférez utiliser la version des backports !</div>

<h3 id="dnssec-trigger">dnssec-trigger</h3>
<p>Testez que l&rsquo;installation de dnssec-trigger est correcte à l&rsquo;aide de la
commande de contrôle <code>dnssec-trigger-control-setup</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# dnssec-trigger-control-setup
</span></span><span style="display:flex;"><span>setup in directory /etc/dnssec-trigger
</span></span><span style="display:flex;"><span>dnssec_trigger_server.key exists
</span></span><span style="display:flex;"><span>dnssec_trigger_control.key exists
</span></span><span style="display:flex;"><span>create dnssec_trigger_server.pem <span style="color:#5bc4bf">(</span>self signed certificate<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>create dnssec_trigger_control.pem <span style="color:#5bc4bf">(</span>signed client certificate<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Signature ok
</span></span><span style="display:flex;"><span><span style="color:#ef6155">subject</span><span style="color:#5bc4bf">=</span>/CN<span style="color:#5bc4bf">=</span>dnssec-trigger-control
</span></span><span style="display:flex;"><span>Getting CA Private Key
</span></span><span style="display:flex;"><span>Setup success. Certificates created.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>run this script again with -i to:
</span></span><span style="display:flex;"><span>    - enable remote-control in unbound.conf
</span></span><span style="display:flex;"><span>    - start unbound-control-setup
</span></span><span style="display:flex;"><span>    - add root trust anchor to unbound.conf
</span></span><span style="display:flex;"><span><span style="color:#815ba4">if</span> you have not <span style="color:#815ba4">done</span> this already
</span></span></code></pre></div><p>Si c&rsquo;est votre cas, c&rsquo;est une bonne chose ! :p</p>
<p>Pensez à redémarrer le service lié à unbound !</p>
<h2 id="configuration">Configuration</h2>
<h3 id="unbound">Unbound</h3>
<p>La configuration d&rsquo;unbound ne pose pas de gros problème, en soit, il faut
veiller à l&rsquo;écriture correcte des informations !</p>
<p>Toutes les variables et leur impact sont expliquées dans la documentation
officielle anglaise : <a href="https://unbound.net/documentation/unbound.conf.html" rel="external">https://unbound.net/documentation/unbound.conf.html</a></p>
<p>Voyons quelques détails dits de sécurité à paramétrer absolument dans votre
propre fichier de configuration, que l&rsquo;on nommera ainsi, pour l&rsquo;exemple : <br>
<code>/etc/unbound/unbound.conf.d/perso.conf</code></p>
<p>Pour tester la configuration de vos fichiers, utilisez la commande <code>unbound-checkconf</code> !</p>
<h4 id="gestion-des-réseaux-autorisés">Gestion des réseaux autorisés</h4>
<p><code>access-control: 127.0.0.0/8 allow</code> ## j&rsquo;autorise l&rsquo;interface de bouclage local
sur la couche IPv4 <br>
<code>access-control: 192.168.1.0/24 allow</code> ## j&rsquo;autorise le réseau local <br>
<code>access-control: 0.0.0.0/0 refuse</code> ## j&rsquo;interdis tout le reste de l&rsquo;Internet !</p>
<p>Le segment réseau peut-être de type IPv4 ou IPv6. L&rsquo;action à allouer peut-être :</p>
<ul>
<li><code>allow</code> permet l&rsquo;accès</li>
<li><code>allow_snoop</code> permet l&rsquo;accès, en utilisant une technique de &ldquo;cache snopping&rdquo;,
qui donne le droit d&rsquo;examiner le contenu en cache.</li>
<li><code>deny</code> refuse l&rsquo;accès - <code>option par défaut, si non spécifiée</code></li>
<li><code>deny_non_local</code>,</li>
<li><code>refuse</code> refuse l&rsquo;accès, tout en envoyant un message d&rsquo;erreur adéquat.</li>
<li>ou <code>refuse_non_local</code></li>
</ul>
<p><em>Pour les autres options, ou afin de mieux saisir les subtilités, merci de lire
la <a href="https://unbound.net/documentation/unbound.conf.html" rel="external">page officielle anglaise</a> !</em></p>
<h4 id="durcir-et-cacher-certaines-informations">Durcir et cacher certaines informations</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">harden-algo-downgrade: no</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">harden-glue: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">hide-identity: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">hide-version: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">private-address: 192.168.0.0/16</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">private-address: 172.16.0.0/12</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">private-address: 10.0.0.0/8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">use-caps-for-id: no</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">val-clean-additional: yes</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li><code>harden-algo-downgrade</code> empêche ou non de choisir l’algorithme le plus faible .
<ul>
<li>Si <code>no</code> est choisi, ce sera l&rsquo;algorithme le plus faible qui sera élu…</li>
<li>Si les zones DNS ne sont pas configurées pour fonctionner correctement
avec cette option, cela peut entraîner des échecs de validation ;
dans ce cas, il faut la mettre sur <code>no</code>. <br>
<em>Cette option n&rsquo;est pas reconnue avec la version Jessie, utilisez la version backports !</em></li>
</ul>
</li>
<li>Les variables <code>private-address</code> renforcent l&rsquo;aspect privé de ces réseaux.
Cela empêche l&rsquo;inclusion de ces segments réseaux dans les réponses DNS,
et protège de la technique des &ldquo;Relais DNS&rdquo;
<em>(qui utilise, par exemple, un navigateur internet comme relais ou proxy réseau)</em>.</li>
<li>La variable <code>use-caps-for-id</code> est expérimentale et peut créer des bogues,
ou résultats incorrects - <em>ne pas l&rsquo;utiliser à moins d&rsquo;être sûr de ce que vous faites…</em></li>
<li>La variable <code>val-clean-additional</code> assure de nettoyer toutes les données DNS non sécurisées</li>
</ul>
<h4 id="optimisation">Optimisation</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">num-threads: 4</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">key-cache-slabs: 8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">infra-cache-slabs: 8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">msg-cache-slabs: 8</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rrset-cache-slabs: 8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">key-cache-size: 16m</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">msg-cache-size: 4m</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">rrset-cache-size: 8m</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">outgoing-range: 206</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">qname-minimisation: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">so-rcvbuf: 1m</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">so-sndbuf: 1m</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">so-reuseport: yes</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>La variable <code>num-thread</code> correspond au nombre de cœurs CPU dont dispose
votre station, soit pour 4 CPU ayant chacun deux cœurs, on lui attribuera
le chiffre <code>8</code>. <br>
Une manière d&rsquo;être sûr du nombre de cœurs utilisés dans votre machine
est d&rsquo;utiliser la commande suivante : <br>
<code>$ cat /proc/cpuinfo | grep processor | wc -l</code></li>
<li>Les variables terminant par le mot <code>*-cache-slabs</code> doivent être paramétrées
au double de la variable <code>num-thread</code>. Ces variables gèrent les conflits
de verrouillage en les diminuant.</li>
<li>La gestion des variables <code>*-cache-size</code> est sensible et doit être ainsi
paramétrée : la variable <code>rrset-cache-size</code> doit être le double de la
variable <code>msg-cache-size</code> ; quant à la variable <code>key-cache-size</code>, elle
doit être elle-même le double de la variable <code>rrset</code>.</li>
<li>La variable <code>outgoing-range</code> qui gère le nombre de connexions par cœurs
CPU doit être ainsi calculée : <br>
<strong>1024 / nb_coeurs_CPU - 50</strong></li>
<li>La variable <code>so-reuseport</code> permet d&rsquo;améliorer significativement les performances
de l&rsquo;usage du protocole UDP !</li>
<li>La variable <code>qname-minimisation</code> envoie un minimum d&rsquo;information DNS pour
améliorer l&rsquo;aspect privé de celles-ci : <br>
<em>Cette option n&rsquo;est pas reconnue avec la version Jessie, utilisez la version backports !</em></li>
<li>Lisez la documentation officielle anglaise pour les options <code>so-rcvbuf</code>,
et <code>so-sndbuf</code> qui doivent être augmentées dans le cas de serveur surchargé.
Autrement, laissez la valeur <code>0</code> par défaut - cela utilise les valeurs systèmes !</li>
</ul>
<h4 id="gestion-des-caches">Gestion des caches</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># garde en cache les bons résultats</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">prefetch: yes</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">cache-min-ttl: 3600</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">cache-max-ttl: 86400</span>
</span></span></code></pre></div><h4 id="gestion-des-journaux">Gestion des journaux</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># gestion logs</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">logfile: /var/log/unbound/unbound.log</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">use-syslog: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">unwanted-reply-threshold: 10000000</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">val-log-level: 2</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">verbosity: 1</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>Si l&rsquo;option <code>unwanted-reply-threshold</code> est définie, le nombre paramétré
total de réponses indésirables est gardé dans chacun des processus.
Ce nombre paramétré atteint déclenche une action défensive de nettoyage
des caches <code>rrset</code> et autres messages, un avertissement est affiché
dans les journaux.
<strong>Il est recommandé de positionner ce nombre à une valeur de 10 Millions</strong> !</li>
<li>L&rsquo;option <code>verbosity</code> est le degré de verbosité des journaux :
<ul>
<li><code>0</code> signifie que seules les erreurs seront affichées ;</li>
<li><code>1</code> que ce sont des informations opérationnelles - <em>valeur par défaut</em> - ;</li>
<li><code>2</code> que celles-ci seront plus détaillées ;</li>
<li><code>3</code> définit les informations par niveau de requêtes et leurs sorties ;</li>
<li><code>4</code> restitue l&rsquo;information du niveau d&rsquo;algorithme utilisé ;</li>
<li><code>5</code>, quant à lui, enregistre l&rsquo;identification des clients en cas d&rsquo;erreurs de cache.</li>
</ul>
</li>
</ul>
<h4 id="bloquer-certains-sites">Bloquer certains sites</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#776e71"># bloque certaines pubs</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;doubleclick.net&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;doubleclick.net A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;googlesyndication.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;googlesyndication.com A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;googleadservices.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;googleadservices.com A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;google-analytics.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;google-analytics.com A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;ads.youtube.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;ads.youtube.com A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;adserver.yahoo.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;adserver.yahoo.com A 127.0.0.1&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-zone: &#34;ask.com&#34; redirect</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">local-data: &#34;ask.com A 127.0.0.1&#34;</span>
</span></span></code></pre></div>
<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p>Pour info, il existe des projets de listes, tels que :</p>
<ul>
<li><strong><a href="https://pgl.yoyo.org/adservers/" rel="external">PGL-Yoyo</a></strong></li>
<li>l&rsquo;excellent <strong><a href="https://www.geoghegan.ca/unbound-adblock.html" rel="external">unbound-badhosts</a></strong></li>
</ul>
<p>Dans le cas d&rsquo;usage de listes, il faut les inclure en utilisant la déclaration : <br>
<code>include: /var/lib/unbound/nom-fichier-liste</code></p>
</div>

<h4 id="gérer-des-statistiques">Gérer des statistiques</h4>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">statistics-interval: 0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">extended-statistics: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">statistics-cumulative: no</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>L&rsquo;option <code>statistics-cumulative</code> est à paramétrer sur <code>yes</code> -
<em>si vous utilisez un outil d&rsquo;affichage graphique des rapports, tel que Munin…</em></li>
</ul>
<h4 id="fichier-roothints">Fichier root.hints</h4>
<p>Le fichier <code>root.hints</code> est une liste des serveurs de noms faisant autorité,
les premiers serveurs DNS, dits <code>roots</code>.</p>
<p>Pour le récupèrer : <br>
<code># curl ftp://FTP.INTERNIC.NET/domain/named.cache -o /var/lib/unbound/root.hints</code></p>
<p>Puis, modifiez le fichier de configuration, pour ajouter : <br>
<code>root-hints: &quot;var/lib/unbound/root.hints</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Pensez à créer un fichier <a href="/fr/sys/debian/unbound-dnssec-trigger/#cron">cron</a> pour mettre-à-jour régulièrement ce
fichier… <br>
normalement, une période de 6 mois suffit.</div>

<h4 id="gestion-dnssec">Gestion DNSSEC</h4>
<p>La gestion DNSSEC se fait par l&rsquo;usage de l&rsquo;outil <a href="https://unbound.net/documentation/unbound-anchor.html" rel="external"><code>unbound-anchor</code></a>
qui crée un fichier de clé nécessaire et l&rsquo;ajout de la variable <code>auto-trust-anchor-file</code>
qui pointe vers ledit fichier de clés.</p>
<p>Exécutez : <br>
<code># unbound-anchor -a &quot;/var/lib/unbound/root.key&quot;</code></p>
<p>La variable <code>auto-trust-anchor-file</code> est normalement déclarée dans le fichier
<code>/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf</code>.
<em>Si ce fichier n&rsquo;existe pas, vous pouvez l&rsquo;ajouter à votre fichier de configuration
personnel, ou créer ledit fichier qui sera pris en charge lors du (re)démarrage
lié au service unbound</em>.</p>
<p>Elle a cette teneur : <br>
<code>auto-trust-anchor-file: &quot;/var/lib/unbound/root.key&quot;</code></p>
<p>De même, il faut ajouter les variables suivantes à votre propre fichier de
configuration :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">harden-below-nxdomain: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">harden-dnssec-stripped: yes</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">harden-referral-path: yes</span>
</span></span></code></pre></div><p><strong>Explications</strong></p>
<ul>
<li>L&rsquo;option <code>harden-referral-path</code> renforce la validation DNSSEC -
c&rsquo;est une option expérimentale, sans norme RFC, et peut poser des problèmes
de performances !</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert">Veillez à redémarrer le service unbound si vous l&rsquo;avez configuré après
l&rsquo;installation et le démarrage post-install !</div>

<h3 id="tests-dnssec">Tests DNSSEC</h3>
<h4 id="dig">Dig</h4>
<p>Un premier test à faire est l&rsquo;usage de la commande <code>dig</code>, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ dig com. SOA +dnssec
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Debian &lt;&lt;&gt;&gt; com. SOA +dnssec
</span></span><span style="display:flex;"><span>;; global options: +cmd
</span></span><span style="display:flex;"><span>;; Got answer:
</span></span><span style="display:flex;"><span>;; -&gt;&gt;HEADER<span style="color:#48b685">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#f99b15">60764</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 14, ADDITIONAL: <span style="color:#f99b15">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">(</span>…<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><p>Ce qu&rsquo;il faut repérer dans la sortie complète de la commande <code>dig</code> est
sur la ligne <code>flags:</code> : il faut la présence du drapeau <code>ad</code> -
<strong>si celui-ci figure bien, c&rsquo;est bon signe !</strong> :D</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ dig com. SOA +dnssec | grep <span style="color:#48b685">&#34;;; flags&#34;</span>
</span></span><span style="display:flex;"><span>;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: <span style="color:#f99b15">1</span>
</span></span></code></pre></div><h4 id="unbound-host">Unbound-host</h4>
<p>L&rsquo;autre commande à utiliser est la commande <code>unbound-host</code> qui permet
de s&rsquo;assurer du même résultat, telle que :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ unbound-host com. -f /var/lib/unbound/root.key -v
</span></span><span style="display:flex;"><span>com. has no address <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>com. has no IPv6 address <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>com. has no mail handler record <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ unbound-host dnssec.cz -f /var/lib/unbound/root.key -v
</span></span><span style="display:flex;"><span>dnssec.cz has address 217.31.205.51 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz has IPv6 address 2001:1488:0:3::5 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">10</span> mail.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">15</span> mx.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">20</span> bh.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># unbound-host dnssec.cz -C /etc/unbound/unbound.conf -v</span>
</span></span><span style="display:flex;"><span><span style="color:#5bc4bf">[</span>1472755792<span style="color:#5bc4bf">]</span> libunbound<span style="color:#5bc4bf">[</span>44222:0<span style="color:#5bc4bf">]</span> debug: switching log to /var/log/unbound/unbound.log
</span></span><span style="display:flex;"><span>dnssec.cz has address 217.31.205.51 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz has IPv6 address 2001:1488:0:3::5 <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">10</span> mail.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">15</span> mx.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>dnssec.cz mail is handled by <span style="color:#f99b15">20</span> bh.nic.cz. <span style="color:#5bc4bf">(</span>secure<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h4 id="dnssec-trigger-1">dnssec-trigger</h4>
<p>Utilisez l&rsquo;outil <code>dnssec-trigger</code> est trivial :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:# dnssec-trigger-control status
</span></span><span style="display:flex;"><span>at 2016-09-01 08:41:22
</span></span><span style="display:flex;"><span>authority 192.33.4.12: OK
</span></span><span style="display:flex;"><span>http ster.nlnetlabs.nl <span style="color:#5bc4bf">(</span>185.49.140.10<span style="color:#5bc4bf">)</span>: OK
</span></span><span style="display:flex;"><span>state: auth secure
</span></span></code></pre></div><h4 id="navigateur-internet">Navigateur internet</h4>
<p>Un moyen visuel est d&rsquo;ouvrir votre navigateur internet favori, puis d&rsquo;aller
sur les sites suivants :</p>
<ul>
<li><a href="http://www.dnssec.cz" rel="external">http://www.dnssec.cz</a> : si, sur la partie droite, vous
voyez une clé verte, c&rsquo;est tout autant bon signe !</li>
<li><a href="https://en.internet.nl" rel="external">https://en.internet.nl</a> :  cliquez sur le lien titré &ldquo;Test my internet connection&rdquo;</li>
</ul>
<h3 id="cron">Cron</h3>
<p>Pensez à créer un fichier cron mensuel <code>/etc/crond.monthly/unbound</code>, pour
mettre-à-jour les fichiers <code>root.hints</code>, et <code>ads server</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#776e71">#!/bin/sh
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># update  file named.cache</span>
</span></span><span style="display:flex;"><span>curl ftp://FTP.INTERNIC.NET/domain/named.cache -o /var/lib/unbound/root.hints
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#776e71"># update file ads servers</span>
</span></span><span style="display:flex;"><span>curl -sS -L --compressed <span style="color:#48b685">&#34;http://pgl.yoyo.org/adservers/serverlist.php?hostformat=unbound&amp;showintro=0&amp;mimetype=plaintext&#34;</span> &gt; /var/lib/unbound/unbound_ad_servers
</span></span><span style="display:flex;"><span>chown unbound:unbound /var/lib/unbound/unbound_ad_servers
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<h3 id="fatal-error-ssl-handshake">fatal error: SSL handshake</h3>
<p>Si vous avez l&rsquo;erreur ci-dessous :</p>
<pre tabindex="0"><code>:# dnssec-trigger-control status
Mar 20 15:08:13 dnssec-trigger-control[2016] fatal error: SSL handshake failed error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed` &lt;/code&gt;
</code></pre><p><strong>redémarrez</strong> d&rsquo;abord le service unbound !</p>
<h2 id="documentations">Documentations</h2>
<ul>
<li>Pour en savoir un peu plus sur l&rsquo;outil, les raisons de son existence et
de son usage, lisez l&rsquo;article de Stéphane Bortzmeyer : <a href="http://www.bortzmeyer.org/dnssec-trigger.html" rel="external">dnssec-trigger, un outil pour mettre DNSSEC à la disposition de M. Toutlemonde</a>…</li>
</ul>
<hr>
<p><em>J&rsquo;ai écrit pour la première fois cet article pour le <a href="https://wiki.debian-fr.xyz/Utiliser_Unbound_avec_DNSSEC" rel="external">wiki de la communauté de Debian-fr.xyz</a> !</em></p>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Sécuriser les connexions, requêtes DNS sous Debian, en utilisant la technologie DNSSEC avec unbound &#43; dnssec-trigger]]></summary>
        <published>2016-09-01T11:37:35+02:00</published>
        <updated>2020-04-20T14:02:35+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:4d512a31-0051-bdc6-d6ff-8eb60f514b3f</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/android/flash-rockchip/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Android 4.4 : Flasher sa tablette Rockchip</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Android" scheme="http://doc.huc.fr.eu.org/fr/tags/android/" />
        <category term="Rockchip" scheme="http://doc.huc.fr.eu.org/fr/tags/rockchip/" />
        <category term="flash" scheme="http://doc.huc.fr.eu.org/fr/tags/flash/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Tout d&rsquo;abord commençons par cet avertissement auquel vous devez consentir,
AUTREMENT passez votre chemin et fermer cette page :</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Je ne suis pas responsable en cas de problème sur votre tablette ; vous
prenez VOS responsabilités !</p>
<p>Pour toute manœuvre root, flash, etc, veillez à ce que votre tablette soit
impérativement à plus de 50 % de charge de batterie… <br>
mieux vaut la brancher électriquement.</p>
<p>/!\ Risque de brickage /!\</p>
</div>

<p><strong>FONCTIONNE À PARTIR D&rsquo;ANDROID 4.4.4</strong></p>
<h2 id="pré-requis">Pré-requis</h2>
<ul>
<li>Que votre tablette soit 
<a class="inside" href="/fr/sys/android/reconnaissance-peripheriques/" title="Lien interne vers l&#39;article : 'Faire reconnaître sa tablette Android sous Linux'">reconnue</a>
 par votre GNU/Linux…</li>
<li><strong>IMPERATIF : ON NE RAPPELLERA JAMAIS ASSEZ L&rsquo;IMPORTANCE DE

    <a class="inside" href="/fr/systeme/android/sauvegarde-restauration/" title="Lien interne vers l&#39;article : ''">SAUVEGARDER</a>

VOS DONNÉES AVANT DE FAIRE TOUTE AUTRE ACTION…
<span class="red">CELA EST DE VOTRE STRICTE RESPONSABILITÉ PERSONNELLE</span>
 !</strong></li>
<li>Téléchargez l&rsquo;outil <a href="http://wiki.radxa.com/Rock/flash_the_image#Linux" rel="external">Linux Upgrade Tool</a></li>
</ul>
<h2 id="utilisation">Utilisation</h2>
<h3 id="adb">adb</h3>
<h4 id="mode-fastboot">Mode fastboot</h4>
<p><strong>Concernant les tablettes Rockchip, oubliez l&rsquo;usage de l&rsquo;outil fastboot</strong> -
cet outil ne fonctionne pas avec !</p>
<h4 id="mode-bootloader">Mode bootloader</h4>
<p>L&rsquo;outil <code>adb</code> va nous servir simplement à redémarrer la tablette dans le
mode nécessaire : le mode bootloader…</p>
<p><code>$ adb reboot-bootloader</code></p>
<p>Dans le mode bootloader, la tablette semble éteinte ; en effet, l&rsquo;écran
est tout noir, et aucune des touches - s&rsquo;il y&rsquo;en a - ne réagit !</p>
<p>De même, dans ce mode, l&rsquo;outil <code>adb</code> ne sera plus d&rsquo;aucune utilité.</p>
<h3 id="rockchip-linux-upgrade-tool">RockChip Linux Upgrade Tool</h3>
<p>Cet outil nous permet donc de flasher et/ou sauvegarder les <strong>partitions</strong>
de nos tablettes.</p>
<p>Il s&rsquo;utilise aussi en mode terminal console.</p>
<p>De même, il est nécessaire d&rsquo;être dans le <a href="/fr/sys/android/flash-rockchip/#mode-bootloader">mode bootloader</a>
afin qu&rsquo;il fonctionne, sinon il ne trouvera pas correctement votre tablette !</p>
<p>Entrez dans le répertoire de l&rsquo;outil, puis en mode console, exécutez-le :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ./upgrade_tool
</span></span><span style="display:flex;"><span>List of rockusb connected
</span></span><span style="display:flex;"><span><span style="color:#ef6155">DevNo</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>   <span style="color:#ef6155">Vid</span><span style="color:#5bc4bf">=</span>0x2207,Pid<span style="color:#5bc4bf">=</span>0x310b,LocationID<span style="color:#5bc4bf">=</span><span style="color:#f99b15">217</span>   Loader
</span></span><span style="display:flex;"><span>Found <span style="color:#f99b15">1</span> rockusb,Select input DevNo,Rescan press &lt;R&gt;,Quit press &lt;Q&gt;:
</span></span></code></pre></div><p>On remarque qu&rsquo;un périphérique est détecté en tant que <code>device numero = 1</code>,
les paramètres <strong>VendorId (Vid)</strong> et <strong>ProductId (Pid)</strong> sont ceux qui
correspondent bien à notre tablette.</p>
<p>Le système attend votre réponse ; tapez le chiffre correspondant,
dans ce cas, le chiffre <code>1</code> !</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>Found <span style="color:#f99b15">1</span> rockusb,Select input DevNo,Rescan press &lt;R&gt;,Quit press &lt;Q&gt;:1
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---------------------Tool Usage ---------------------
</span></span><span style="display:flex;"><span>Help:             H
</span></span><span style="display:flex;"><span>Quit:             Q
</span></span><span style="display:flex;"><span>Version:          V
</span></span><span style="display:flex;"><span>Clear Screen:     CS
</span></span><span style="display:flex;"><span>------------------Upgrade Command ------------------ &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>ChooseDevice:      CD
</span></span><span style="display:flex;"><span>SwitchDevice:      SD
</span></span><span style="display:flex;"><span>UpgradeFirmware:   UF &lt;Firmware&gt;
</span></span><span style="display:flex;"><span>UpgradeLoader:      UL &lt;Loader&gt;
</span></span><span style="display:flex;"><span>DownloadImage:      DI &lt;-p|-b|-k|-s|-r|-m image&gt; <span style="color:#5bc4bf">[</span>parameter file<span style="color:#5bc4bf">]</span> &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>DownloadBoot:      DB &lt;Loader&gt; &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>EraseFlash:      EF &lt;Loader|firmware&gt; &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>LowerFormat:      LF
</span></span><span style="display:flex;"><span>----------------Professional Command ----------------- &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>TestDevice:      TD
</span></span><span style="display:flex;"><span>ResetDevice:      RD
</span></span><span style="display:flex;"><span>ReadFlashID:      RID
</span></span><span style="display:flex;"><span>ReadFlashInfo:      RFI
</span></span><span style="display:flex;"><span>ReadChipInfo:      RCI
</span></span><span style="display:flex;"><span>ReadSector:      RS  &lt;BeginSec&gt; &lt;SectorLen&gt; <span style="color:#5bc4bf">[</span>-decode<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>File<span style="color:#5bc4bf">]</span> &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>WriteSector:      WS  &lt;BeginSec&gt; &lt;File&gt; &lt;/nowiki&gt;
</span></span><span style="display:flex;"><span>ReadLBA:      RL  &lt;BeginSec&gt; &lt;SectorLen&gt; <span style="color:#5bc4bf">[</span>File<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>WriteLBA:      WL  &lt;BeginSec&gt; &lt;File&gt;
</span></span><span style="display:flex;"><span>EraseBlock:      EB &lt;CS&gt; &lt;BeginBlock&gt; &lt;BlokcLen&gt; <span style="color:#5bc4bf">[</span>--Force<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>-------------------------------------------------------
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Rockusb&gt;
</span></span></code></pre></div><p>À savoir que certaines commandes sont directement fonctionnelles, en mode
console, en tant qu&rsquo;argument de l&rsquo;outil. <br>
Ce sont les commandes <code>UF</code>, <code>UL</code>, <code>DI</code>, <code>DB</code>, <code>EL</code>, <code>LF</code>, <code>SD</code>, <code>RD</code>…</p>
<p>Tel que : <code>./upgrade_tool UF update.img</code></p>
<p>De même, la commande RD signifiant <strong>Reset Device</strong> est en fait la commande
pour redémarrer la tablette - c&rsquo;est un reboot, ni plus ni moins !</p>
<p>Depuis la version 1.13 de l&rsquo;outil &ldquo;Linux Upgrade Tool&rdquo;, il est possible
de flasher simultanément plusieurs partitions.</p>
<p>Tel que : <code>./upgrade_tool DI -k,-s kernel.img, system.img</code></p>
<h4 id="flasher-une-rom-originale">Flasher une ROM originale</h4>
<p>Très simplement, en utilisant l&rsquo;option <code>UF</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;UF PiPO_M9pro_update_andriod4.4_20140504.img
</span></span><span style="display:flex;"><span>Loading firmware...
</span></span><span style="display:flex;"><span>Support Type:RK31   FW Ver:4.4.02   FW Time:2014-05-04 17:38:05
</span></span><span style="display:flex;"><span>Loader ver:2.10   Loader Time:2013-12-27 22:12:16
</span></span><span style="display:flex;"><span>Upgrade firmware ok.
</span></span></code></pre></div><p>ou, directement en mode CLI : <code>./upgrade_tool UF PiPO_M9pro_update_andriod4.4_20140504.img</code></p>
<h4 id="flasher-une-rom-custom">Flasher une ROM Custom</h4>
<p>Pour flasher une ROM Custom, telles que les RileyROM, FinlessRom, il faut,
dans un premier temps décompresser, l&rsquo;archive de la ROM.</p>
<p>Copier le répertoire RileyRom dans celui de l&rsquo;outil &ldquo;Linux Upgrage Tool&rdquo; ;
cela simpliefiera l&rsquo;usage.</p>
<ul>
<li>Il nous faut formater la tablette :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;LF
</span></span><span style="display:flex;"><span>Lower Format Device,total<span style="color:#5bc4bf">(</span>8192<span style="color:#5bc4bf">)</span>,current<span style="color:#5bc4bf">(</span>7460<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>Lower Format Device OK.
</span></span></code></pre></div><ul>
<li>Ensuite, il faut flasher le Loader :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;UL RileyROM/RK3188Loader<span style="color:#5bc4bf">(</span>L<span style="color:#5bc4bf">)</span>_V2.10.bin
</span></span><span style="display:flex;"><span>Loading loader...
</span></span><span style="display:flex;"><span>Support Type:RK310B   Loader ver:2.10   Loader Time:2013-12-27 22:12:16
</span></span><span style="display:flex;"><span>Upgrade loader ok
</span></span></code></pre></div><ul>
<li>Après cette seconde étape, il semble nécessaire de faire reconnaître à
nouveau la tablette :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;CD
</span></span><span style="display:flex;"><span>List of rockusb connected
</span></span><span style="display:flex;"><span><span style="color:#ef6155">DevNo</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>   <span style="color:#ef6155">Vid</span><span style="color:#5bc4bf">=</span>0x2207,Pid<span style="color:#5bc4bf">=</span>0x310b,LocationID<span style="color:#5bc4bf">=</span><span style="color:#f99b15">210</span>   Loader
</span></span><span style="display:flex;"><span>Found <span style="color:#f99b15">1</span> rockusb,Select input DevNo,Rescan press &lt;R&gt;,Quit press &lt;Q&gt;:1
</span></span></code></pre></div><ul>
<li>Il devient nécessaire de flasher le fichier <code>parameter</code> :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;DI -p RileyROM/parameter
</span></span><span style="display:flex;"><span>Download parameter ok.
</span></span></code></pre></div><ul>
<li>Puis de terminer en flashant les différentes &ldquo;partitions&rdquo; nécessaires :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;DI -k,-b,-r,-m,-s RileyROM/kernel.img,RileyROM/boot.img,RileyROM/recovery.img,RileyROM/misc.img,RileyROM/system.img
</span></span><span style="display:flex;"><span>Download kernel start...
</span></span><span style="display:flex;"><span>Download image ok.
</span></span><span style="display:flex;"><span>Download boot start...
</span></span><span style="display:flex;"><span>Download image ok.
</span></span><span style="display:flex;"><span>Download recovery start...
</span></span><span style="display:flex;"><span>Download image ok.
</span></span><span style="display:flex;"><span>Download misc start...
</span></span><span style="display:flex;"><span>Download image ok.
</span></span><span style="display:flex;"><span>Download system start...
</span></span><span style="display:flex;"><span>Download image ok.
</span></span></code></pre></div><p>Si après avoir lancé la commande, le système vous répond avec ce message <br>
<code>buffer overflow detected: ./upgrade_tool terminated</code> <br>
le logiciel vient de s&rsquo;arrêter ! <br>
<strong>Relancez-le en utilisant la commande <code>DI</code> fichier après fichier</strong>…</p>
<ul>
<li>Ceci étant fait, et si tous les messages annoncent <code>ok</code>, il ne reste
plus qu&rsquo;à redémarrer la tablette :</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ Rockusb&gt;RD
</span></span><span style="display:flex;"><span>Reset Device OK.
</span></span></code></pre></div><h2 id="dépannage">Dépannage</h2>
<h3 id="mode-maskrom">Mode maskrom</h3>
<p>Sortir du mode maskrom n&rsquo;est pas chose aisée car vous n&rsquo;avez aucun voyant,
ni aucun moyen visuel pour être sûr !</p>
<p>L&rsquo;outil <code>upgrade_tool</code> nous y aide :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ ./upgrade_tool
</span></span><span style="display:flex;"><span>List of rockusb connected
</span></span><span style="display:flex;"><span><span style="color:#ef6155">DevNo</span><span style="color:#5bc4bf">=</span><span style="color:#f99b15">1</span>   <span style="color:#ef6155">Vid</span><span style="color:#5bc4bf">=</span>0x2207,Pid<span style="color:#5bc4bf">=</span>0x310b,LocationID<span style="color:#5bc4bf">=</span><span style="color:#f99b15">265</span>   Maskrom
</span></span><span style="display:flex;"><span>Found <span style="color:#f99b15">1</span> rockusb,Select input DevNo,Rescan press &lt;R&gt;,Quit press &lt;Q&gt;:
</span></span></code></pre></div><p>Comme nous le voyons sur la ligne <code>DevNo</code>, à la fin de celle-ci, est indiqué
<code>Maskrom</code> - au lieu de <code>Loader</code> !</p>
<p>On lance le formatage de l&rsquo;image avec <strong>upgrade_tool</strong> :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>:$ Rockusb&gt;UF PiPO_M9pro_update_andriod4.4_20140504.img
</span></span><span style="display:flex;"><span>Loading firmware...
</span></span><span style="display:flex;"><span>Support Type:RK31   FW Ver:4.4.02   FW Time:2014-05-04 17:38:05
</span></span><span style="display:flex;"><span>Loader ver:2.10   Loader Time:2013-12-27 22:12:16
</span></span><span style="display:flex;"><span>Upgrade firmware ok.
</span></span></code></pre></div><p>Une fois le message <code>Upgrade firmware ok</code> affiché, la tablette redémarrera
toute seule !</p>
<h3 id="erreurs">Erreurs</h3>
<h4 id="buffer-overflow-detected-upgrade_tool-terminated">buffer overflow detected: ./upgrade_tool terminated</h4>
<p>Le logiciel vient de terminer son processus, à cause d&rsquo;un problème de
gestion de la mémoire. Veuillez relancer le processus fichier après fichier !</p>
<h4 id="loading-loader-failed">Loading loader failed</h4>
<span class="red">Vérifiez le chemin de votre fichier !!!</span>

<p>Il y a de fortes probabilités pour que le chemin entré ne corresponde pas
à celui dans votre système de fichier…</p>
<h4 id="no-found-match-deviceplease-press-cd-to-choose-device">No found match device,please press CD to choose device</h4>
<p>Le logiciel vous dit d&rsquo;utiliser la commande <code>CD</code> pour faire (re?)connaître
votre tablette, à nouveau !</p>
<h4 id="reset-device-quitcreating-comm-object-failed">Reset Device quit,Creating comm object failed</h4>
<p>Le programme n&rsquo;arrive pas à faire redémarrer la tablette… <br>
c&rsquo;est signe qu&rsquo;il y a un problème de communication entre celle-ci et votre ordinateur.</p>
<p>Cherchez à comprendre la raison !</p>
<hr>
<h2 id="documentation">Documentation</h2>
<ul>
<li>J&rsquo;ai écrit ce tutoriel pour la première fois sur le <a href="https://wiki.debian-fr.xyz/Flasher_sa_tablette_Rockchip_-_Android_4.4_-" rel="external">wiki de la communauté Debian-fr.xyz</a> !</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment flasher sa tablette de type Rockchip sous Android 4.4.4]]></summary>
        <published>2016-07-16T13:30:51+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:972a4446-4f7b-2c1a-8d6c-04e52993cfb5</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/android/sauvegarde-restauration/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Sauvegarder/Restaurer sa tablette Android</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Android" scheme="http://doc.huc.fr.eu.org/fr/tags/android/" />
        <category term="adb" scheme="http://doc.huc.fr.eu.org/fr/tags/adb/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Tout d&rsquo;abord commençons par cet avertissement auquel vous devez consentir,
AUTREMENT passez votre chemin et fermer cette page :</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Je ne suis pas responsable en cas de problème sur votre tablette ; vous
prenez VOS responsabilités !</p>
<p>Pour toute manœuvre root, flash, etc, veillez à ce que votre tablette soit
impérativement à plus de 50 % de charge de batterie… <br>
mieux vaut la brancher électriquement.</p>
<p>/!\ Risque de brickage /!\</p>
</div>

<h2 id="pré-requis">Pré-requis</h2>
<ul>
<li>Que votre tablette soit 
<a class="inside" href="/fr/sys/android/reconnaissance-peripheriques/" title="Lien interne vers l&#39;article : 'Faire reconnaître sa tablette Android sous Linux'">reconnue</a>

sous GNU/Linux !</li>
<li>Il n&rsquo;y a pas besoin d&rsquo;être en mode administrateur pour effectuer les
opérations de sauvegarde et restauration.</li>
</ul>
<h2 id="sauvegarde">Sauvegarde</h2>
<p>La commande principale est :</p>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab</code></p>
<p>Si l&rsquo;option <code>-f</code> n&rsquo;est pas spécifiée, le fichier <code>backup.ab</code> sera créé dans
le répertoire courant où est exécutée la commande de sauvegarde…</p>
<p>L&rsquo;aide nous restitue :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>  adb backup <span style="color:#5bc4bf">[</span>-f &lt;file&gt;<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>-apk|-noapk<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>-obb|-noobb<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>-shared|-noshared<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>-all<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>-system|-nosystem<span style="color:#5bc4bf">]</span> <span style="color:#5bc4bf">[</span>&lt;packages...&gt;<span style="color:#5bc4bf">]</span>
</span></span><span style="display:flex;"><span>                               - write an archive of the device<span style="color:#48b685">&#39;s data to &lt;file&gt;.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                 If no -f option is supplied then the data is written
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                 to &#34;backup.ab&#34; in the current directory.
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                 (-apk|-noapk enable/disable backup of the .apks themselves
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                    in the archive; the default is noapk.)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                 (-obb|-noobb enable/disable backup of any installed apk expansion
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                    (aka .obb) files associated with each application; the default
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                    is noobb.)
</span></span></span><span style="display:flex;"><span><span style="color:#48b685">                                 (-shared|-noshared enable/disable backup of the device&#39;</span>s
</span></span><span style="display:flex;"><span>                                    shared storage / SD card contents; the default is noshared.<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                                 <span style="color:#5bc4bf">(</span>-all means to back up all installed applications<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                                 <span style="color:#5bc4bf">(</span>-system|-nosystem toggles whether -all automatically includes
</span></span><span style="display:flex;"><span>                                    system applications; the default is to include system apps<span style="color:#5bc4bf">)</span>
</span></span><span style="display:flex;"><span>                                 <span style="color:#5bc4bf">(</span>&lt;packages...&gt; is the list of applications to be backed up.  If
</span></span><span style="display:flex;"><span>                                    the -all or -shared flags are passed, <span style="color:#815ba4">then</span> the package
</span></span><span style="display:flex;"><span>                                    list is optional.  Applications explicitly given on the
</span></span><span style="display:flex;"><span>                                    command line will be included even <span style="color:#815ba4">if</span> -nosystem would
</span></span><span style="display:flex;"><span>                                    ordinarily cause them to be omitted.<span style="color:#5bc4bf">)</span>
</span></span></code></pre></div><h3 id="sauvegarde-applications">Sauvegarde applications</h3>
<p><code>:$ adb backup -f nom_fichier_sauvegarde.ab -apk -obb</code></p>
<p>Cette commande sauvegarde les fichiers apk des applications installées.</p>
<p>L&rsquo;option par défaut est <code>-noapk</code> qui signifie que les fichiers apk ne seront
pas sauvegardés !</p>
<p>L&rsquo;option <code>-obb</code> implique la sauvegarde des fichiers relatifs aux applications
installées, tels que fichiers de sauvegarde, de config, etc… <br>
par défaut, c&rsquo;est l&rsquo;option <code>-noobb</code> qui est active !</p>
<hr>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab package1 package2 package_n</code></p>
<p>Sauvegarde les noms des applications concernées !</p>
<h3 id="sauvegarde-partitions">Sauvegarde partitions</h3>
<p>L&rsquo;outil <code>adb</code> peut servir à sauvegarder indirectement les partitions de votre
tablette…</p>
<p>Pour cela, il faut télécharger l&rsquo;outil <a href="http://files.androtab.info/rk2818/devel/rkdump_android.zip" rel="external">rkdump</a> !</p>
<p>Puis l&rsquo;utiliser ainsi :</p>
<pre tabindex="0"><code>`$ adb push rkdump /data/
`$ adb shell chmod 0755 /data/rkdump`
</code></pre><h3 id="sauvegarde-sd-carte">Sauvegarde SD Carte</h3>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab -shared</code></p>
<p>Sauvegarde le contenu de la SD Carte, ainsi que de tout répertoire de stockage
partagé.</p>
<p>Il est bien sûr nécessaire d&rsquo;avoir une SD Carte dans votre appareil…</p>
<p>Par défaut, c&rsquo;est l&rsquo;option <code>-noshared</code> qui est active et implique la non
sauvegarde !</p>
<h3 id="sauvegarde-système">Sauvegarde Système</h3>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab -system</code></p>
<p>Par défaut, c&rsquo;est l&rsquo;option <code>-nosystem</code> qui est activée, ce qui a pour effet
de ne pas inclure les applications systèmes !</p>
<h3 id="sauvegarde-tout">Sauvegarde tout</h3>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab -all</code></p>
<p>Cette commande implique la sauvegarde de toutes les applications installées,
dont les applications systèmes.</p>
<p>Cette option intègre l&rsquo;option <code>-system</code> !</p>
<h3 id="sauvegarde-pertinente">Sauvegarde Pertinente</h3>
<p>Le moyen pertinent de sauvegarder tout correctement est, <em>sans s&rsquo;occuper
du contenu de la SD Carte</em> :</p>
<p><code>$ adb backup -f nom_fichier_sauvegarde.ab -apk -obb -all</code></p>
<h2 id="restauration">Restauration</h2>
<p><code>$ adb restore nom_fichier_sauvegarde.ab</code></p>
<p>Tout ce qui concerne le contenu du fichier de sauvegarde sera restauré !</p>
<hr>
<ul>
<li>J&rsquo;ai écrit pour la première fois ce tutoriel sur le <a href="https://wiki.debian-fr.xyz/Sauvegarder_et_Restaurer_sa_tablette_Android" rel="external">wiki de la communauté Debian-fr.xyz</a> !</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment sauvegarder ou restaurer une tablette Android]]></summary>
        <published>2016-07-16T11:09:03+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:f9a7a2f6-19da-c589-5e4d-d68cd9159553</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/android/reconnaissance-peripheriques/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Faire reconnaître sa tablette Android sous Linux</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Android" scheme="http://doc.huc.fr.eu.org/fr/tags/android/" />
        <category term="adb" scheme="http://doc.huc.fr.eu.org/fr/tags/adb/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Tout d&rsquo;abord commençons par cet avertissement auquel vous devez consentir,
AUTREMENT passez votre chemin et fermer cette page :</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Je ne suis pas responsable en cas de problème sur votre tablette ; vous
prenez VOS responsabilités !</p>
<p>Pour toute manœuvre root, flash, etc, veillez à ce que votre tablette soit
impérativement à plus de 50 % de charge de batterie… <br>
mieux vaut la brancher électriquement.</p>
<p>/!\ Risque de brickage /!\</p>
</div>

<p>Tablettes testées :</p>
<ul>
<li><strong>Archos 101 Oxygen</strong> : <span class="green">OK</span>
 - VendorId: 0e79; ProductId: 50f8</li>
<li><strong>Cdisplay</strong> : <span class="green">OK</span>
 - VendorId:201e; ProductId: 4289</li>
<li><strong>Pipo M8 HD</strong> : <span class="green">OK</span>
 - VendorId: 2207; ProductId: 0010</li>
<li><strong>Teclast X89 Kindow</strong> : <span class="green">OK</span>
 - VendorId: 8087; ProductId: 0a5f</li>
</ul>
<h2 id="pré-requis">Pré-requis</h2>
<ul>
<li>Utiliser un ordinateur ayant des ports USB 2 - <span class="red">pas USB 3</span>
 :
avec ces ports, il peut y avoir des difficultés de reconnaissance !</li>
<li>Pour Debian :
<ul>
<li><span class="red">avant wheezy, oubliez</span>
</li>
<li>pour wheezy, utilisez les dépôts backports.</li>
<li>pour Jessie, et Sid, utilisez les dépôts officiels.</li>
</ul>
</li>
<li>Que votre tablette soit en mode &ldquo;Débogage USB&rdquo; :
<strong>Paramètres &gt; {} Outils pour les développeurs &gt; Déboguage USB [v]</strong></li>
<li>Et, bien sûr, une connection Internet fonctionnelle…</li>
</ul>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p>Tant que le mode “Débogage USB” n&rsquo;est pas actif, ou que vous ne pouvez pas
l&rsquo;activer, pas la peine de continuer… en effet, sans ce mode actif, le périphérique
NE PEUT être reconnu !</p>
<p>Ce mode s&rsquo;active différemment selon la version d&rsquo;Android.</p>
<p>Veuillez-vous référer à la documentation technique de votre périphérique…</p>
</div>

<h2 id="installation">Installation</h2>
<p>Il faut installer les outils suivants : <br>
<code>android-tools-adb android-tools-fastboot android-tools-fsutils</code></p>
<p>Les deux derniers ne sont pas strictement nécessaires…</p>
<p>À vous de le faire, selon votre convenance - terminal-console, synaptic, etc.</p>
<h2 id="configuration">Configuration</h2>
<p>Pour faire reconnaître proprement la tablette, il faut :</p>
<ul>
<li>Dans un premier temps, connectez votre tablette, sur le port micro-usb -
<em>et, non host</em> - par câble usb à votre ordinateur. <br>
<em>(Peu importe le mode de connexion USB : MTP, PTP ou stockage USB)</em>.</li>
<li>Ouvrez un terminal-console pour taper dedans la commande <code>lsusb</code>.</li>
</ul>
<p>Exemple : Pour une tablette PiPo, telle la M8HD, vous aurez comme réponse :</p>
<pre tabindex="0"><code>$ lsusb
(…)
Bus 002 Device 014: ID 2207:0010`
</code></pre><p>L&rsquo;information importante est celle après <code>ID</code>, dans ce cas : <code>2207:0010</code></p>
<ul>
<li>la première série de 4 chiffres avant le symbole &lsquo;:&rsquo; est l&rsquo;identifiant
fabriquant - nommé <strong>idVendor</strong> -</li>
<li>la seconde série de 4 chiffres après le symbole &lsquo;:&rsquo; est l&rsquo;identifiant du
produit - nommé <strong>idProduct</strong> -</li>
</ul>
<p>Il nous faut créer une règle <code>udev</code>, et pour cela, écrire le fichier <code>/etc/udev/rules.d/51-android.rules</code> : <br>
<code>SUBSYSTEM==&quot;usb&quot;, ATTR{idVendor}==&quot;2207&quot;, MODE=&quot;0666&quot;, GROUP=&quot;plugdev&quot;</code></p>
<p>⇒ Modifiez dans cette règle selon les informations idVendor, idProduct que
vous avez trouvées…</p>
<p>Ensuite, il nous faut créer/modifier un autre fichier utile <code>~/.android/adb_usb.ini</code>,
pour y ajouter l&rsquo;information de l&rsquo;identifiant du fabriquant de la manière
suivante, soit un <code>0x</code> suivi de idVendor, un identifiant par ligne.</p>
<p>Pour l&rsquo;exemple ci-dessus, ce serait <code>0x2207</code></p>
<p>⇒ Assurez-vous que votre utilisateur linux soit dans le groupe <code>plugdev</code>…
sinon ajoutez-le ! <br>
<code># usermod -G plugdev votre_id_utilisateur</code></p>
<p>⇒ Enregistrez le fichier, puis redémarrez udev : <br>
<code># service udev restart</code></p>
<h2 id="utilisation">Utilisation</h2>
<p>Pour être sûr que la tablette soit reconnue, utilisez la commande <code>adb devices</code> :</p>
<pre tabindex="0"><code>:$ adb devices
List of devices attached
WAWJM5UMUW   device
</code></pre><p>Pour le reste, tapez la commande <code>adb</code> ; elle vous restituera les différentes
options !</p>
<h2 id="erreurs">Erreurs</h2>
<h3 id="adb--commande-introuvable">adb : commande introuvable</h3>
<p>Êtes-vous sûr d&rsquo;avoir <a href="/fr/sys/android/reconnaissance-peripheriques/#installation">installé</a> les outils <code>adb</code> ???</p>
<h3 id="adb-devices--rien-nest-affiché">&lsquo;adb devices&rsquo; : rien n&rsquo;est affiché</h3>
<p>Si rien n&rsquo;est reconnu, et donc qu&rsquo;aucun device n&rsquo;apparaît, c&rsquo;est que vous
avez peut-être mal renseigné le fichier <code>/etc/udev/rules.d/51-android.rules</code>
et/ou n&rsquo;avez pas redémarré le système udev !</p>
<p>Si malgré tout, vous êtes absolument sûr d&rsquo;avoir bien rempli le fichier
en question, et d&rsquo;avoir redémarré udev, il peut être intéressant d&rsquo;effectuer
la manipulation suivante :</p>
<ul>
<li>Créer le fichier <code>~/.android/adb_usb.ini</code>, et écrivez dedans <code>0x</code> suivi de
votre idVendor</li>
</ul>
<p>Pour la tablette PiPo M8HD, ce sera : <code>0x2207</code></p>
<ul>
<li>Redémarrer le serveur adb : <code>:# adb kill-server</code></li>
<li>Exécutez à nouveau : <code>adb devices</code></li>
</ul>
<h3 id="adb-devices---no-permissions"><code>adb devices</code> : ???????????? no permissions</h3>
<p>Lorsque je tape <code>adb devices</code>, le périphérique n&rsquo;est pas reconnu et il est
affiché <strong>???????????? no permissions</strong></p>
<p>Il vous faut tuer le serveur, le redémarrer avec des droits administrateur
ensuite le périphérique apparaîtra !</p>
<pre tabindex="0"><code>:$ adb kill-server
:# adb start-server
</code></pre><h3 id="adb-devices--offline"><code>adb devices</code> : offline</h3>
<p>Lorsque je tape <code>adb devices</code>, le périphérique est reconnu mais affiché <strong>offline</strong></p>
<pre tabindex="0"><code>:$ adb devices
List of devices attached
WAWJM5UMUW   offline
</code></pre><p>Il vous faudra alors :</p>
<ul>
<li>désactiver l&rsquo;option &ldquo;Débogage USB&rdquo;…</li>
<li>déconnecter/reconnecter votre tablette à l&rsquo;ordinateur, en débranchant/rebranchant
le câble USB.</li>
<li>activer à nouveau l&rsquo;option &ldquo;Débogage USB&rdquo;</li>
</ul>
<p>À ce moment-là, essayez à nouveau la commande <code>adb devices</code> ; vous devriez
voir apparaître votre périphérique…  correctement !</p>
<h3 id="error-while-loading-shared-libraries-libncursesso5">error while loading shared libraries: libncurses.so.5</h3>
<p>Si vous fonctionnez avec une distribution GNU/Linux 64 bits, c&rsquo;est qu&rsquo;il
vous manque les librairies pour l&rsquo;architecture 32 bits !</p>
<h2 id="documentations">Documentations</h2>
<p>Vous pouvez lire mes autres articles, pour :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/android/root/" title="Lien interne vers l&#39;article : 'Rooter sa tablette Android 4.x'">Rooter sa tablette Android 4.x</a>

</li>
<li>
<a class="inside" href="/fr/sys/android/sauvegarde-restauration/" title="Lien interne vers l&#39;article : 'Sauvegarder/Restaurer sa tablette Android'">Sauvegarder/Restaurer sa tablette Android</a>

</li>
<li>
<a class="inside" href="/fr/sys/android/flash-rockchip/" title="Lien interne vers l&#39;article : 'Android 4.4 : Flasher sa tablette Rockchip'">Android 4.4 : Flasher sa tablette Rockchip</a>

</li>
</ul>
<hr>
<h3 id="remerciements">Remerciements</h3>
<p>Ce tutoriel n&rsquo;aurait pas existé sans le fourmillement d&rsquo;idées glanées ici et là…
merci à leurs auteurs respectifs !</p>
<ul>
<li>forum XDA : <a href="http://forum.xda-developers.com/showthread.php?t=2262494" rel="external">http://forum.xda-developers.com/showthread.php?t=2262494</a></li>
<li><a href="http://sorrodje.alter-it.org/index.php?article12/ubuntu-rooter-flasher-rom-sdk-android" rel="external">http://sorrodje.alter-it.org/index.php?article12/ubuntu-rooter-flasher-rom-sdk-android</a></li>
</ul>
<hr>
<ul>
<li>J&rsquo;ai écrit ce tutoriel la première fois sur le <a href="https://wiki.debian-fr.xyz/Reconna%C3%AEtre_sa_tablette" rel="external">wiki de la communauté Debian-fr.xyz</a> !</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment faire reconnaitre sa tablette Android sous Linux]]></summary>
        <published>2016-07-13T09:37:51+02:00</published>
        <updated>2017-01-08T04:26:51+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:2a590054-4a4f-b33d-2884-2304711adbe6</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/android/root/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Rooter sa tablette Android 4.x</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Android" scheme="http://doc.huc.fr.eu.org/fr/tags/android/" />
        <category term="adb" scheme="http://doc.huc.fr.eu.org/fr/tags/adb/" />
        <content type="html"><![CDATA[<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="description">Description</h2>
<p>Tout d&rsquo;abord commençons par cet avertissement auquel vous devez consentir,
AUTREMENT passez votre chemin et fermer cette page :</p>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><p>Je ne suis pas responsable en cas de problème sur votre tablette ; vous
prenez VOS responsabilités !</p>
<p>Pour toute manœuvre root, flash, etc, veillez à ce que votre tablette soit
impérativement à plus de 50 % de charge de batterie… <br>
mieux vaut la brancher électriquement.</p>
<p>/!\ Risque de brickage /!\</p>
</div>

<p><strong>FONCTIONNE AVEC ANDROID 4.2.2, 4.4.2, 4.4.4</strong></p>
<p>Tablette testée :</p>
<ul>
<li><strong>Archos 101 Oxygen</strong> : <span class="red">KO</span>
 - n&rsquo;est pas possible
nativement car en mode production !</li>
<li><strong>Pipo M8 HD</strong> : <span class="green">OK</span>
 - 4.2.2, 4.4.2</li>
<li><strong>Teclast X89 Kindow</strong> : <span class="green">OK</span>
 - 4.4.4</li>
</ul>
<h2 id="pré-requis">Pré-requis</h2>
<ul>
<li>Que votre tablette soit en mode &ldquo;Débogage USB&rdquo;…</li>
<li>Que votre tablette soit 
<a class="inside" href="/fr/sys/android/reconnaissance-peripheriques/" title="Lien interne vers l&#39;article : 'Faire reconnaître sa tablette Android sous Linux'">reconnue</a>

par Linux…</li>
<li>Il est prudent de 
<a class="inside" href="/fr/sys/android/sauvegarde-restauration/" title="Lien interne vers l&#39;article : 'Sauvegarder/Restaurer sa tablette Android'">sauvegarder</a>

votre tablette avant !</li>
<li>Obtenir <a href="http://download.chainfire.eu/supersu" rel="external">Supersu</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>TOUTES les manipulations, que nous allons faire, se font dans un terminal console !</p>
<p>Décompressez l&rsquo;archive de Supersu, précédemment téléchargée et allez dans
le répertoire de l&rsquo;archive décompressée.</p>
<p>Vous trouverez dans l&rsquo;archive de SuperSu des répertoires portant les noms
relatifs aux différentes architectures matérielles de tablettes gérées :</p>
<ul>
<li>&ldquo;arm&rdquo; équivaut à &ldquo;arm&rdquo; - à savoir : c&rsquo;est la valeur par défaut !</li>
<li>&ldquo;armeabi-v7a&rdquo; = &ldquo;armv7&rdquo;</li>
<li>&ldquo;x86&rdquo; = &ldquo;x86&rdquo;</li>
<li>&ldquo;mip&rdquo; ou &ldquo;mips&rdquo; = &ldquo;mips&rdquo;</li>
<li>&ldquo;arm64-v8a&rdquo; = &ldquo;arm64&rdquo;</li>
<li>&ldquo;mips64&rdquo; = &ldquo;mips64&rdquo;</li>
<li>&ldquo;x86_64&rdquo; = &ldquo;x64&rdquo;</li>
</ul>
<p>Si dans l&rsquo;archive de SuperSu, vous n&rsquo;avez pas de répertoire correspondant
à votre version, c&rsquo;est que vous avez une ancienne version… <br>
téléchargez la plus récente !</p>
<h2 id="utilisation">Utilisation</h2>
<p>Vérifions que la tablette soit &ldquo;vue&rdquo; :</p>
<pre tabindex="0"><code>:$ adb devices
List of devices attached
WAWJM5UMUW   device
</code></pre><h3 id="mode-écriture">Mode écriture</h3>
<p>Entrons la tablette dans le mode en écriture nécessaire :</p>
<pre tabindex="0"><code>:$ adb wait-for-device
:$ adb root
:$ adb remount
</code></pre><p>Si la commande <code>adb root</code> restitue <code>adbd cannot run as root in production build</code>,
<span class="red">cela semble compromis</span>
 !</p>
<p>Si la commande <code>adb remount</code> ne fonctionne pas :</p>
<ul>
<li>Si la commande précédente <code>adb root</code> a fonctionné ; essayez la commande : <br>
<code>adb shell mount -o remount,rw /system</code> <br>
<span class="red">Si elle ne fonctionne pas non plus… cela ne sert à rien
    d'aller plus loin !</span>
</li>
<li>Si la commande précédente <code>adb root</code> n&rsquo;a pas fonctionné, et que vous avez
le message suivant <code>remount failed: permission denied</code>… <br>
<span class="red">inutile d'aller plus loin !</span>
</li>
</ul>
<h3 id="détections">Détections</h3>
<h4 id="version-android">Version Android</h4>
<p>Détectons votre version Android :</p>
<pre tabindex="0"><code>$ adb shell getprop ro.build.version.sdk
17
</code></pre><p>Si cela ne fonctionne pas, essayez ceci :</p>
<pre tabindex="0"><code>$ adb shell cat /system/build.prop &amp;#124; grep &#34;ro.build.version.sdk=&#34;
ro.build.version.sdk=17
</code></pre><ul>
<li>La version du sdk qui correspond au chiffre <code>17</code> est Jelly Bean.</li>
<li>Si la commande vous restitue <code>19</code>, nous avons bien KitKat.</li>
</ul>
<h4 id="architecture-matérielle">Architecture matérielle</h4>
<p>Détectons votre architecture :</p>
<pre tabindex="0"><code>:$ adb shell getprop ro.product.cpu.abi
armeabi-v7a
</code></pre><p>Si cela ne fonctionne pas, essayez ceci :</p>
<pre tabindex="0"><code>:$ adb shell cat /system/build.prop /default.prop &amp;#124; grep -m 1 &#34;ro.product.cpu.abi=&#34;
ro.product.cpu.abi=armeabi-v7a
</code></pre><p>Les valeurs détectées correspondent aux architectures nommées par SuperSU !</p>
<h3 id="rootage">Rootage</h3>
<p>Dirigez-vous dans le répertoire de l&rsquo;archive décompressée de SuperSU !</p>
<p>En partant du principe que l&rsquo;architecture détectée correspond à &ldquo;armv7&rdquo; -
<em>adaptez selon votre architecture</em> - passons à la phase de rootage proprement dite :</p>
<pre tabindex="0"><code>:$ adb push armv7/su /system/xbin/su
:$ adb shell chown root.root /system/xbin/su
:$ adb shell chmod 0755 /system/xbin/su
</code></pre><p>Installons SuperSu :</p>
<pre tabindex="0"><code>:$ adb push common/Superuser.apk /system/app/Superuser.apk
:$ adb shell chown root.root /system/app/Superuser.apk
:$ adb shell chmod 0644 /system/app/Superuser.apk
</code></pre><h4 id="kitkat--étapes-supplémentaires">KitKat : étapes supplémentaires</h4>
<p>Copier <code>su</code> en <code>daemonsu</code>, qui sera lancé en tant que service par le système
au démarrage :</p>
<pre tabindex="0"><code>:$ adb shell cp /system/xbin/su /system/xbin/daemonsu
:$ adb shell chown root.root /system/xbin/daemonsu
:$ adb shell chmod 0755 /system/xbin/daemonsu
</code></pre><p>La deuxième étape est d&rsquo;injecter le fichier <code>install-recovery.sh</code> -
<em>c&rsquo;est lui qui lancera daemonsu au démarrage</em> - :</p>
<pre tabindex="0"><code>:$ adb push common/install-recovery.sh /system/etc/install-recovery.sh
:$ adb shell chown root.root /system/etc/install-recovery.sh
:$ adb shell chmod 0755 /system/etc/install-recovery.sh
</code></pre><h3 id="pour-finir">Pour finir</h3>
<p>Redémarrons proprement la tablette :</p>
<pre tabindex="0"><code>:$ adb reboot
adb kill-server
</code></pre><p>Une fois, la tablette redémarrée, entrez dans votre session, il vous sera
certainement demander de mettre-à-jour le binaire SuperSu : faites-le !
Sinon, cliquez sur l&rsquo;icône de Supersu, et faites-la mise-à-jour qui sera demandée.</p>
<p>Puis cliquez sur le binaire SuperSU - qui la première fois, vous demandera
d&rsquo;installer le binaire SU - choisissez le mode normal, quand il vous sera
proposé &ldquo;Normal&rdquo; ou &ldquo;TWRP&rdquo;.</p>
<p>Si le binaire vous informe que tout est ok, redémarrez à nouveau la tablette !</p>
<h2 id="documentations">Documentations</h2>
<p>Vous pouvez lire mes autres articles, pour :</p>
<ul>
<li>
<a class="inside" href="/fr/sys/android/sauvegarde-restauration/" title="Lien interne vers l&#39;article : 'Sauvegarder/Restaurer sa tablette Android'">Sauvegarder/Restaurer sa tablette Android</a>

</li>
<li>
<a class="inside" href="/fr/sys/android/flash-rockchip/" title="Lien interne vers l&#39;article : 'Android 4.4 : Flasher sa tablette Rockchip'">Android 4.4 : Flasher sa tablette Rockchip</a>

</li>
</ul>
<hr>
<ul>
<li>J&rsquo;ai écrit ce tutoriel la première fois sur le <a href="https://wiki.debian-fr.xyz/Rooter_sa_tablette" rel="external">wiki de la communauté Debian-fr.xyz</a> !</li>
</ul>
<hr>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment rooter sa tablette Android (4.2.2, 4.4.2, 4.4.4)]]></summary>
        <published>2016-07-13T09:37:51+02:00</published>
        <updated>2016-12-16T10:19:51+02:00</updated>
    </entry>
    
    <entry>
        <id>urn:uuid:276baa37-e0df-77bf-3bc9-b2fa436634bb</id>
        <link href="http://doc.huc.fr.eu.org/fr/sys/debian/nvidia-optimus-bumblebee/" rel="alternate" type="text/html" />
        <title>Stéphane HUC :: IT Log :: Debian : Nvidia Optimus Bumblebee</title>
        <author>
            <name>Stéphane HUC</name>
        </author>
        <category term="Debian" scheme="http://doc.huc.fr.eu.org/fr/tags/debian/" />
        <category term="nvidia" scheme="http://doc.huc.fr.eu.org/fr/tags/nvidia/" />
        <category term="Optimus" scheme="http://doc.huc.fr.eu.org/fr/tags/optimus/" />
        <category term="Bumblebee" scheme="http://doc.huc.fr.eu.org/fr/tags/bumblebee/" />
        <content type="html"><![CDATA[<p>Depuis Debian 11 Bullseye, publiée en Août 2021, cet article est obsolète.
Merci de lire ce
<a href="https://www.debian-fr.org/t/doc-nvidia-optimus-bumblebee-dans-quel-etat-gere-infos/79959/9?u=pengouinpdt" rel="external">post sur le forum Debian-fr.org</a>,
qui explique ce qu&rsquo;il faut faire.</p>
<hr>
<p>Je reprends le propos ici :</p>
<blockquote>
<p>D&rsquo;après la page du wiki officiel Debian « Nvidia Optimus »,
section &quot; Using NVIDIA PRIME Render Offload&quot; 17, il est recommandé :</p>
</blockquote>
<ul>
<li>de désactiver dans le Bios UEFI, l’option « Secure BOOT » !</li>
<li>il n’y a(ura) plus besoin d’installer le projet Bumblebee ; s&rsquo;il est installé,
il faut le supprimer absolument.</li>
<li>d&rsquo;installer directement le pilote propriétaire nVidia depuis les dépôts Debian
puis utiliser à minima la variable d’environnement <code>__NV_PRIME_RENDER_OFFLOAD=1</code>
et d’ajouter dans certains cas la suivante <code>__GLX_VENDOR_LIBRARY_NAME=nvidia</code>.</li>
</ul>
<p>⇒ Dans le contexte de Steam, il faut modifier les propriétés de jeux, en
ajoutant le paramètrage complet :
<code>__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%</code></p>
<hr>
<p>Plus d’informations et autres astuces, sur la page officielle nVidia <a href="https://us.download.nvidia.com/XFree86/Linux-x86_64/450.57/README/primerenderoffload.html" rel="external">primerenderoffload</a> :</p>
<ul>
<li><a href="https://us.download.nvidia.com/XFree86/Linux-x86_64/450.57/README/primerenderoffload.html" rel="external">https://us.download.nvidia.com/XFree86/Linux-x86_64/450.57/README/primerenderoffload.html</a></li>
</ul>
<p>De même, il est possible de se faire aider sur le forum des développeurs nvidia :</p>
<ul>
<li><a href="https://forums.developer.nvidia.com/c/gpu-graphics/linux/148" rel="external">https://forums.developer.nvidia.com/c/gpu-graphics/linux/148</a></li>
</ul>
<hr>
<div class="tab-info i-deprecated"><strong>Obsolète</strong></div>
<div class="alert alert-deprecated" role="alert"><strong>La documentation écrite ci-dessous semble obsolète… Il vaut mieux ne plus tenir compte de ces informations, qui restent à titre d&#39;&#34;information historique&#34;. Veuillez en tenir compte et prendre vos responsabilités !</strong></div>

<h2 id="présentation">Présentation</h2>
<p>Nvidia a créé une technologie hybride, appelée Optimus. Cette technologie
a pour but d&rsquo;utiliser la puce graphique intégrée, généralement de marque
Intel, ainsi que le processeur graphique, couplée à la première puce, de
marque Nvidia. Cela permet de faire fonctionner le GPU Nvidia, à la demande,
lors de nécessités de fonctions 3D poussées (vidéos, jeux…), et de
&ldquo;rendre la main&rdquo; à l&rsquo;IGP Intel, soulageant ainsi la batterie, pour le reste.</p>
<p>Un développeur a créé un projet, nommé Bumblebee, qui nous apporte une
certaine gestion de cette technologie. Elle n&rsquo;est pas complètement gérée,
mais est fonctionnelle ! <br>
Néanmoins, la gestion HDMI n&rsquo;est pas accessible…</p>
<ul>
<li>La page du projet : <a href="http://www.bumblebee-project.org/" rel="external">http://www.bumblebee-project.org/</a></li>
<li>Le dépôt git : <a href="https://github.com/Bumblebee-Project/Bumblebee" rel="external">https://github.com/Bumblebee-Project/Bumblebee</a></li>
</ul>
<h2 id="informations">Informations</h2>

<div class="tab-info i-danger">Danger</div><div class="alert alert-danger" role="alert"><strong>NE SURTOUT PAS CHERCHER À INSTALLER LES PILOTES NVIDIA PAR TOUTE AUTRE MÉTHODE !!!</strong> <br>
Si jamais vous l&rsquo;avez fait, désinstallez tout avant :
<code># apt remove --purge nvidia-*</code></div>

<p>Nativement sous Linux, cette technologie n&rsquo;est pas pleinement supportée.<br>
Officiellement, depuis la version 319.12, Nvidia apporte son support, en
phase bêta - cela nécessite de pouvoir connecter l&rsquo;écran au GPU Nvidia ;
cette option est modifiable par certains BIOS récents. <br>
Si votre pilote est plus ancien, ou que vous n&rsquo;êtes pas dans ce cas de
configuration matérielle, cette page est vraiment faite pour vous.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>Ne pas utiliser le pilote Nvidia 340</strong>… la technologie Optimus n&rsquo;est
pas gérée, pour Linux - oubli/erreur du fabriquant ! <br>
C&rsquo;est la version <strong>par défaut pour Jessie</strong> !!!</div>

<hr>
<h2 id="vérifications">Vérifications</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Ce tutoriel est plutôt à l&rsquo;intention d&rsquo;utilisateurs avancés de Debian -
et, traite plus particulièrement de l&rsquo;installation du projet Bumblebee pour
sa gestion avec le pilote &ldquo;privatif&rdquo; nvidia. Merci d&rsquo;en tenir compte… <br>
Si vous avez besoin d&rsquo;un tutoriel décrivant étape par étape, préférez
la <a href="https://debian-facile.org/doc:materiel:cartes-graphique:nvidia:optimus" rel="external">lecture de ce tutoriel</a> !</div>

<h3 id="vérification-matérielle">Vérification matérielle</h3>
<p>Si vous voulez être sûr d&rsquo;avoir une telle technologie, entrez la commande
suivante dans votre terminal préféré :
<code>lspci | egrep &quot;VGA|3D|Display&quot;</code></p>
<p>Si le système vous répond, ainsi, avec deux lignes, telles que :</p>
<pre tabindex="0"><code>:$ lspci | egrep &#34;VGA|3D|Display&#34;
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)
01:00.0 VGA compatible controller: NVIDIA Corporation GF108 [GeForce GT 540M] (rev ff)
</code></pre><p>Alors, c&rsquo;est votre cas !</p>
<p><strong>Explications</strong></p>
<ul>
<li>la première information &lsquo;01:00.0&rsquo; est relative à l&rsquo;option BusID - elle
peut-être différente selon votre configuration matérielle.</li>
</ul>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p><strong>INFORMATION</strong> : Ne cherchez pas à utiliser le pilote libre &rsquo;nouveau'
si votre carte graphique de fabriquant nvidia n&rsquo;est pas supportée par
celui-ci.</p>
<ol>
<li>
<p>Pour savoir, si elle est supportée, lisez la <a href="https://nouveau.freedesktop.org/wiki/CodeNames/" rel="external">page du &ldquo;code name&rdquo; fournie par le projet nouveau</a>,
et recherchez la mention correspondante à votre GPU.</p>
</li>
<li>
<p>Puis selon le &ldquo;code name&rdquo; correspondant, lisez cette <a href="https://nouveau.freedesktop.org/wiki/VideoAcceleration/" rel="external">page</a>
pour connaître le support ou non de votre carte vidéo.</p>
</li>
<li>
<p><strong>Si votre carte graphique n&rsquo;est pas supportée, utilisez directement le
projet Bumblebee avec le pilote privatif !</strong></p>
</li>
</ol>
<p>Pour récapituler, il faut la version du serveur X suivante pour :</p>
<ul>
<li>
<p>l&rsquo;architecture matérielle NV110, nommée <strong>Maxwell</strong> : <strong><a href="https://cgit.freedesktop.org/nouveau/xf86-video-nouveau/commit/?h=xf86-video-nouveau-1.0.14&amp;id=e6479845ec0db20dc733c621b7967b751840a552" rel="external">xf86-video-nouveau-1.0.14</a></strong></p>
</li>
<li>
<p>l&rsquo;architecture matérielle NV130, nommée <strong>Pascal</strong> : <strong><a href="https://cgit.freedesktop.org/nouveau/xf86-video-nouveau/commit/?id=e472b47d15634a864c8c981ed588d882aceaf26b" rel="external">xf86-video-nouveau-1.0.15</a></strong></p>
</li>
</ul>
<p>La version du serveur X est disponible à partir de :</p>
<ul>
<li>Jessie : <a href="https://packages.debian.org/jessie/xserver-xorg-video-nouveau" rel="external">1.0.11</a></li>
<li>Stretch : <a href="https://packages.debian.org/stretch/xserver-xorg-video-nouveau" rel="external">1.0.13</a></li>
<li>Buster : <a href="https://packages.debian.org/buster/xserver-xorg-video-nouveau" rel="external">1.0.16</a></li>
</ul>
<p>De fait, <strong>les cartes de famille Maxwell, ou Pascal, n&rsquo;ont pas le support
du pilote libre ni pour Jessie, ni pour Stretch</strong>. <br>
<strong>Pour les plus récentes, passez directement à nvidia</strong>. <br>
<strong>Si votre carte graphique n&rsquo;est pas supportée, ou semble mal supportée du
fait de saccades, utilisez directement le projet Bumblebee avec le pilote privatif !</strong></p>
</div>

<h3 id="vérification-modules-kernel">Vérification modules kernel</h3>
<p>Vérifiez que vous n&rsquo;avez aucun des deux modules suivants installés et/ou chargés :
<code>:$ lsmod | egrep -i &quot;nouveau|vga_switcheroo&quot;</code></p>
<p>Si c&rsquo;est le cas, il faudra les décharger, à l&rsquo;aide de la commande :
`:# modprobe -r nom-du-module</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong> : Il est possible que vous ayez le message d&rsquo;erreur suivant
&lsquo;modprobe:FATAL:Module nouveau in use&rsquo; lorsque vous cherchez à décharger
le pilote… veuillez lire le chapitre concernant
l&rsquo;<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#modprobefatalmodule-nouveau-in-use">erreur</a>, ci-dessous, en fin de page, à
la section sus-nommée… <br>
sans trop vous en soucier, non plus !</div>

<h3 id="pré-requis">Pré-requis</h3>
<p>Vérifier que vous avez bien les binaires, ci-dessous, installés :</p>
<ul>
<li>Pour architecture 32bits :
<code>:# apt install gcc make linux-headers-i586 dkms bbswitch-dkms</code></li>
<li>Pour architecture 32bits (Stretch Backports) : <br>
<code>:# apt install -t stretch-backports gcc make linux-headers-i686 dkms bbswitch-dkms</code></li>
<li>Pour architecture 64bits : <br>
<code>:# apt install gcc make linux-headers-amd64 dkms bbswitch-dkms</code></li>
</ul>
<p>Puis, assurez-vous que le module bbswitch fonctionne bien : <br>
<code>:# modprobe bbswitch load_state=0</code></p>
<h3 id="dernières-vérifications">Dernières vérifications</h3>
<p>Vérifiez que vous n&rsquo;avez pas de fichier de configuration <code>/etc/X11/xorg.conf</code>,
ni de répertoire <code>/etc/X11/xorg.conf.d/</code> - si c&rsquo;est le cas, supprimez-le
avec vos droits administrateur !</p>
<hr>
<h2 id="installation">Installation</h2>
<h3 id="gestion-des-dépôts">Gestion des dépôts</h3>
<p>La <a href="https://wiki.debian.org/fr/Bumblebee" rel="external">page wiki du projet Debian</a> nous informe que les utilisateurs de <a href="http://packages.debian.org/search?suite=jessie&amp;searchon=names&amp;keywords=bumblebee" rel="external">Jessie</a>,
et <a href="http://packages.debian.org/search?suite=sid&amp;searchon=names&amp;keywords=bumblebee" rel="external">Sid</a> peuvent installer Bumblebee à partir des dépôts officiels Debian.</p>
<p><em>Depuis le 26.05.2013, cela semble aussi le cas pour les utilisateurs des
dépôts <a href="http://backports.debian.org/changes/wheezy-backports.html" rel="external">Wheezy-Backports</a> !</em></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>NOTE</strong> : Il est aussi nécessaire de s&rsquo;assurer d&rsquo;avoir paramétré les dépôts
<code>contrib</code> et <code>non-free</code>.</div>

<h3 id="ajout-support-architecture-32-bits">Ajout support architecture 32 bits</h3>
<p><strong>Architecture 64 bits</strong> : Pensez à <strong>ajouter la gestion de l&rsquo;architecture i386</strong>,
et installez en plus le package <code>primus-libs-ia32</code> - anciennement <em>primus-libs:i386</em> -
si vous voulez faire fonctionner un binaire 32 bits.</p>
<h3 id="choisir-le-pilote">Choisir le pilote</h3>
<p>Mettez-à-jour votre système, et installez les binaires :</p>
<ul>
<li><code>bumblebee</code> - rien que pour l&rsquo;usage du <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#pilote-nouveau">pilote libre nouveau</a>,</li>
<li>ou <code>bumblebee-nvidia</code> - pour l&rsquo;usage du <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#pilote-nvidia">pilote privatif Nvidia</a>.</li>
</ul>
<h4 id="pilote-nouveau">pilote nouveau</h4>
<p><code>:# apt update &amp;&amp; apt install bumblebee mesa-utils</code></p>
<p>Ainsi que le fait remarquer le <a href="https://metadata.ftp-master.debian.org/changelogs//main/x/xserver-xorg-video-nouveau/xserver-xorg-video-nouveau_1.0.16-1_changelog" rel="external">changelog</a>, il est suggéré d&rsquo;installer
à-partir de la version 1.0.15-2 du serveur X nouveau le firmware <em>firmware-misc-nonfree</em>. <br>
<strong>Si vous exécutez Buster, ou supérieure, faites-le !</strong></p>
<h4 id="pilote-nvidia">pilote nvidia</h4>
<p><code>:# apt update &amp;&amp; apt install bumblebee-nvidia primus nvidia-kernel-dkms nvidia-xconfig nvidia-settings nvidia-vdpau-driver vdpau-va-driver mesa-utils xserver-xorg-video-nvidia linux-headers-$(uname -r)</code></p>
<p><strong>Préférez la version des backports si elle est disponible !</strong></p>
<p><em>(En 2015, vous auriez pu subir ce <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#bogue-735049">bogue 735049</a>…)</em></p>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><p><strong>INFORMATION</strong> : Il semble nécessaire d&rsquo;installer le binaire <a href="http://www.virtualgl.org/" rel="external">VirtualGL</a>,
requis par Optirun ; malheureusement il n&rsquo;est pas dans les dépôts Debian.</p>
<p>Téléchargez-le à partir de la <a href="https://sourceforge.net/projects/virtualgl/files/" rel="external">page de téléchargement du projet</a>…
<strong>ne téléchargez pas l&rsquo;archive .tar.gz</strong> ; cliquez sur le répertoire portant
le nom de la dernière version en cours, puis vous trouverez parmi les
différents fichiers un fichier portant le nom suivant <em>virtualgl_num-version_arch.deb</em>
(où &rsquo;num-version&rsquo; est le numéro de version en cours, et &lsquo;arch&rsquo; est à choisir
selon votre architecture…)… <br>
puis installez-le à l&rsquo;aide de l&rsquo;outil <code>dpkg</code>…</p>
<p><em><a href="https://fixmynix.com/install-and-configure-nvidia-optimus-with-bumblebee-in-debian/" rel="external">source</a></em></p>
</div>

<hr>
<h2 id="configuration">Configuration</h2>
<h3 id="ajout-groupe-bumblebee">Ajout groupe Bumblebee</h3>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><strong>ATTENTION</strong> : Normalement cette étape est exécutée automatiquement lors
de l&rsquo;installation. À ne faire que si vous avez le <a>message d&rsquo;erreur</a>
ci-dessous !</div>

<p>Avec les droits administrateur, il vous faut ensuite ajouter votre utilisateur
au groupe bumblebee :  <br>
<code>:# adduser ID_USER bumblebee</code></p>
<p>Pensez à redémarrer votre session, voire votre machine !</p>
<h3 id="configurations-supplémentaires">Configurations supplémentaires</h3>
<p>Les configurations ci-dessous ne sont normalement pas nécessaires !</p>
<p>Ces informations sont utiles au cas où se pose un souci relatif à
l&rsquo;<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#utilisation">utilisation</a>.</p>
<h4 id="configuration-pilote-nvidia">Configuration pilote nvidia</h4>
<p>Il peut être utile d&rsquo;informer Bumblebee d&rsquo;utiliser le module <em>nvidia</em>,
au lieu du module <em>nouveau</em>. Par défaut, il utilise le pilote nouveau.</p>
<p>Avec des droits administrateur, il faut d&rsquo;abord modifier le fichier
<code>/etc/bumblebee/bumblebee.conf</code>
pour configurer la ligne <code>DRIVER=</code>, telle que : <br>
<code>DRIVER=nvidia</code></p>

<div class="tab-info i-tip">Astuce</div><div class="alert alert-tip" role="alert">Si <code>nvidia</code> ne fonctionne pas, changez pour <code>DRIVER=nvidia-current</code>.</div>

<p>Pensez à <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrer le service</a> !</p>
<h4 id="liste-noire--module-nouveau">Liste noire : module nouveau</h4>
<p>Cela peut être intéressant de &ldquo;blacklister&rdquo; le module nouveau, si et seulement si,
vous voulez n&rsquo;utiliser que le pilote privatif Nvidia. <br>
<em>(afin d&rsquo;être sûr que ce ne sera pas ce module qui gérera la carte Nvidia, mais
bien le pilote Nvidia !)</em></p>
<p>Créez, avec vos droits administrateur, le fichier <code>/etc/modprobe.d/nouveau-blacklist.conf</code>,
et ajoutez ces écritures :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">blacklist nouveau</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">blacklist lbm-nouveau</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">options nouveau modeset</span><span style="color:#5bc4bf">=</span><span style="color:#48b685">0</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias nouveau off</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">alias lbm-nouveau off</span>
</span></span></code></pre></div><h4 id="upgrade">upgrade</h4>
<p>Si le système ne le fait pas tout seul, comme un grand, pensez à faire
courir à nouveau le module pour votre kernel, avec vos droits administrateur !</p>
<p>Avec la commande <code>dkms</code>, telle que : <br>
<code>:# dpkg-reconfigure nvidia-kernel-dkms</code></p>
<h4 id="gestion-de-la-batterie">Gestion de la batterie</h4>
<p>Pour gérer correctement l&rsquo;énergie de la batterie lors de l&rsquo;usage de la
carte Nvidia, il peut être nécessaire de créer le fichier
<code>/etc/modprobe.d/bbswitch.conf</code> et d&rsquo;y ajouter ceci - normalement le projet
Bumblebee installe le paquet <strong>bbswitch</strong> et le gère correctement - : <br>
<code>options bbswitch load_state=0 unload_state=0</code></p>
<p>Ensuite, il vous faut modifier le fichier <code>/etc/bumblebee/bumblebee.conf</code>
et configurer les lignes <code>PMMethod</code> ainsi : <br>
<code>PMMethod=bbswitch</code></p>
<p>Pensez à <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrer le service</a> !</p>
<p>Ensuite, <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#test-du-fonctionnement-de-la-batterie">testez le bon fonctionnement</a>
de la gestion de la batterie.</p>
<h4 id="steam">Steam</h4>
<ol>
<li>
<p>Ajoutez la variable d&rsquo;environnement <code>OPTIMUS_PREFIX</code> :
<code>:# sh -c 'echo OPTIMUS_PREFIX=\&quot;primusrun\&quot; &gt;&gt; /etc/environment'</code></p>
</li>
<li>
<p>Déloguez-vous de votre session pour vous reconnectez !</p>
</li>
<li>
<p>Puis, pour chaque jeu, dont vous voulez profiter d&rsquo;optirun, il faut
modifier les propriétés de lancement de celui-ci. <br>
Exécutez Steam, allez dans votre librairie de jeux, sélectionnez le jeu
en question, puis faites un clic droit dessus, et choisissez le menu &ldquo;Properties&rdquo;. <br>
Ensuite, cliquez sur le bouton [SET LAUNCH OPTIONS] et spécifiez dans le
champ l&rsquo;information qui suit : <br>
<code>$OPTIMUS_PREFIX %command%</code> <br>
Une solution plus simple est d&rsquo;éditer les propriétés de lancement et d&rsquo;ajouter
directement : <br>
<code>primusrun %command%</code></p>
</li>
</ol>
<hr>
<h2 id="utilisation">Utilisation</h2>
<p>Toutes les étapes précédentes de <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#verifications">vérifications</a>, d&rsquo;
<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#installation">installations</a> et de <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#configuration">configurations</a>,
ayant été faites, vous pouvez être sûr que Bumblebee fonctionne grâce au
binaire <strong>optirun</strong>. <br>
Donc, pour activer la gestion du GPU Nvidia, il faut faire précéder toute
commande par l&rsquo;usage de la commande <code>optirun</code>.</p>
<p><code>:$ optirun [optirun-options] &lt;application&gt; [application-parameters]</code></p>
<p>Pour trouver la liste des options de optirun, vous pouvez, soit :</p>
<ul>
<li>lire la page du manuel avec la commande <code>man optirun</code>,</li>
<li>exécuter : <code>$ optirun --help</code></li>
</ul>
<h3 id="test">Test</h3>
<p>Le premier test que vous pouvez faire est :  <br>
<code>:$ optirun glxgears -info</code></p>
<h3 id="panel-nvidia">Panel Nvidia</h3>
<p><strong>Ne cherchez pas à l&rsquo;utiliser en cliquant sur l&rsquo;icône correspondante, dans
votre menu, cela ne fonctionnera pas.</strong></p>
<p>Il vous faut le lancer ainsi - c&rsquo;est le seul moyen ! - : <br>
<code>:$ optirun nvidia-settings -c :8</code></p>
<h3 id="redémarrage-du-service-bumblebeed">Redémarrage du service bumblebeed</h3>
<p>Selon votre version de debian :</p>
<ul>
<li>Si <strong>initd</strong> : <code>/etc/init.d/bumblebeed restart</code></li>
<li>Si <strong>service</strong> : <code>service bumblebeed restart</code></li>
<li>Si <strong>systemd</strong> : <code>systemctl restart bumblebeed</code></li>
</ul>
<hr>
<h2 id="dépannage">Dépannage</h2>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert">Concernant la gestion des erreurs ci-dessous, après avoir appliqué la correction,
pensez à <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrer le service</a> !</div>

<h3 id="bogue-735049">Bogue 735049</h3>
<p><strong>ATTENTION</strong> : Depuis Janvier 2014, lors de l&rsquo;installation du package
<em>bumblebee-nvidia</em>, il est possible que vous ayez droit à un fenêtre d&rsquo;avertissement
vous demandant de créer le fichier xorg.conf !</p>
<ul>
<li><strong>NE LE FAITES PAS !</strong></li>
<li><strong>NE LAISSEZ PAS</strong> l&rsquo;outil debconf créer le fichier pour vous !</li>
<li><strong>N&rsquo;EXÉCUTEZ PAS</strong> l&rsquo;outil nvidia-xconfig !</li>
</ul>
<p><em>Bogue <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=735049" rel="external">735049</a> qui semble être résolu depuis octobre 2015 !</em></p>
<h3 id="errorcannot-access-secondary-gpu---error-could-not-enable-discrete-graphics-card">[ERROR]Cannot access secondary GPU - error: Could not enable discrete graphics card</h3>
<p>Vérifiez le journal de dmesg pour savoir si vous trouvez la référence suivante : <br>
<code>Refused to change power state, currently in D3</code></p>
<p>Cela semble être dû à un problème de gestion de l&rsquo;ACPI <em>(souvent retrouvés
dans des portables de marque Dell)</em> avec le noyau 4.8 et plus récent.</p>
<h4 id="pmmethodnone">PMMethod=none</h4>
<p>Éditez <code>/etc/bumblebee/bumblebee.conf</code> pour paramétrez <code>PMMethod=none</code>.</p>
<h4 id="pcie_port_pmoff">pcie_port_pm=off</h4>
<p>Si vous utilisez le pilote nvidia, il peut être utile de modifier le
fichier <code>/etc/default/grub</code>  pour ajouter la désactivation suivante : <br>
<code>pcie_port_pm=off</code></p>
<p>Mettez-à-jour votre grub et redémarrez votre ordinateur :</p>
<pre tabindex="0"><code>:# update-grub
:# shutdown -r now
</code></pre><p><em><a href="https://github.com/Bumblebee-Project/bbswitch/issues/140#issuecomment-403306682" rel="external">source</a></em></p>
<h3 id="errorcannot-access-secondary-gpu---error-could-not-load-gpu-driver">[ERROR]Cannot access secondary GPU - error: Could not load GPU driver</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>NOTE</strong> : Cette erreur peut-être générée par un des différents points suivants…
veuillez les vérifier un par un, pas tous en même temps, cela ne sert à rien.
Une fois qu&rsquo;un point est vérifié/corrigé, <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrez le service</a>
et essayez à nouveau votre commande. <br>
Si cela ne fonctionne pas, passez au point suivant qui peut aider à la résolution,
et répétez le même processus de vérification/modification puis redémarrage
du service adéquat - <strong>bien comprendre et accepter que cela ne réglera pas
forcément votre problème !</strong></div>

<h4 id="modification-de-driver">Modification de &ldquo;Driver&rdquo;</h4>
<p>Ouvrez le fichier <code>/etc/bumblebee/bumblebee.conf</code>, avec les droits administrateur,
et modifiez la ligne <code>Driver=</code> par <code>Driver=nvidia</code>.</p>
<h4 id="modification-de-kerneldriver">Modification de &ldquo;KernelDriver&rdquo;</h4>
<p>Ouvrez le fichier <code>/etc/bumblebee/bumblebee.conf</code>, avec les droits administrateur,
et dans la section <code>[Driver-nvidia]</code>, vérifiez la ligne <code>KernelDriver=</code>
qu&rsquo;elle soit bien ainsi <code>KernelDriver=nvidia-current</code>.</p>
<p>Pour vérifier le nom du module nvidia, exécutez les deux commandes suivantes :</p>
<pre tabindex="0"><code>:# modinfo nvidia
:# modinfo nvidia-current`
</code></pre><p>Normalement vous devriez avoir ces retours :</p>
<pre tabindex="0"><code>:# modinfo nvidia
modinfo: ERROR: Module nvidia not found.
</code></pre><p>ou, par exemple :</p>
<pre tabindex="0"><code>:#  modinfo nvidia-current
filename: /lib/modules/3.16.0-4-amd64/updates/dkms/nvidia-current.ko
alias: char-major-195-*
version: 340.96
supported: external
license: NVIDIA
(…)
</code></pre><p>Si jamais, vous avez un résultat sur <code>modinfo nvidia</code>, modifiez la ligne
<code>KernelDriver=</code> ainsi <code>KernelDriver=nvidia</code> &lt;= <strong>ce qui ne devrait pas avoir
lieu !</strong></p>
<p>Si aucune des deux commandes ne retourne rien, vous avez eu un souci lors
de l&rsquo;installation &lt;= <strong>ce n&rsquo;est pas normal ; cherchez la raison !</strong></p>
<p><em>Bogue <a href="https://bugs.debian.org/717687" rel="external">717687</a></em></p>
<h3 id="errorcannot-access-secondary-gpu---error-xorg-ee-devdricard0-failed-to-set-drm-interface-version-14-permission-denied">[ERROR]Cannot access secondary GPU - error: [XORG] (EE) /dev/dri/card0: failed to set DRM interface version 1.4: Permission denied</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>NOTE</strong> : Cette erreur peut-être générée par un des différents points suivants…
veuillez les vérifier un par un, pas tous en même temps, cela ne sert à rien.
Une fois qu&rsquo;un point est vérifié/corrigé, <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrez le service</a>
et essayez à nouveau votre commande. <br>
Si cela ne fonctionne pas, passez au point suivant qui peut aider à la résolution,
et répétez le même processus de vérification/modification puis redémarrage
du service adéquat - <strong>bien comprendre et accepter que cela ne réglera pas
forcément votre problème !</strong></div>

<h4 id="vérification-xserver-xorg-video-nvidia">Vérification xserver-xorg-video-nvidia</h4>
<p>Vérifiez l&rsquo;installation du paquet &ldquo;xserver-xorg-video-nvidia&rdquo; - <strong>s&rsquo;il n&rsquo;est
pas installé, faites-le !</strong></p>
<h4 id="modification-fichier-xorgconfnvidia">Modification fichier xorg.conf.nvidia</h4>
<p>Ouvrez le fichier <code>/etc/bumblebee/xorg.conf.nvidia</code>, et ajoutez les informations
suivantes :</p>
<div class="highlight"><pre tabindex="0" style="color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#06b6ef">Section &#34;Screen&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Identifier &#34;Default Screen&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">Device &#34;DiscreteNvidia&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#06b6ef">EndSection</span>
</span></span></code></pre></div><p><em><strong>Bogue <a href="https://bugs.debian.org/756522" rel="external">756522</a></strong> qui touche <strong>Debian Jessie</strong>, à-propos des <strong>Bumblebee
versions</strong> : <strong>3.2.1-5</strong>, <strong>3.2.1-7</strong> et <strong>nvidia versions</strong> : <em>340.</em></em>*,</p>
<h4 id="vérification-prise-en-charge-par-nouveau">Vérification prise en charge par nouveau</h4>
<ul>
<li>Si vous avez installé Bumblebee pour fonctionner avec le pilote libre
&rsquo;nouveau&rsquo;, vérifiez le <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#verification-materielle">support de votre GPU</a>
nvidia par le pilote.</li>
<li>Si votre version de GPU est bien prise en charge par le pilote &rsquo;nouveau&rsquo;,
vérifiez l&rsquo;écriture de l&rsquo;<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#erreur-identifiant-buspci">identifiant de Bus PCI</a>,
tel que ci-dessous.</li>
<li>S&rsquo;il n&rsquo;est pas pris-en-charge, installez la version &ldquo;<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#pilote-nivida">Bumblebee+nvidia</a>&rdquo;.</li>
</ul>
<h4 id="erreur-identifiant-buspci">Erreur Identifiant BusPCI</h4>
<p>Profitez-en pour vérifier l&rsquo;écriture de l&rsquo;identifiant du Bus PCI relatif
à votre carte graphique Nvidia.</p>

<div class="tab-info i-warning">Attention</div><div class="alert alert-warning" role="alert"><p><strong>ATTENTION</strong> : L&rsquo;identifiant de Bus PCI doit bien être écrit ainsi :
<strong>BusID &ldquo;PCI:01:00:0&rdquo;</strong> - <em>et non pas BusID &ldquo;PCI:01:00.0&rdquo;</em>.</p>
<p>Parfois il peut être nécessaire de mettre en commentaire l&rsquo;identifiant de
Bus PCI, pour que cela puisse fonctionner correctement… <br>
ce qui normalement est le cas d&rsquo;une installation par défaut !</p>
</div>

<h4 id="incompatibilité-xorg--118">Incompatibilité Xorg &gt;= 1.18</h4>
<p>Si le serveur X est <strong>&gt;= 1.18</strong> et que votre Debian est une Testing, ou une Sid,
il semble exister une incompatibilité entre le projet Bumblebee et le
paquet <strong>xserver-xorg-legacy</strong>, donc <strong>virez ce dernier</strong>, s&rsquo;il est installé !</p>
<p><em><a href="https://github.com/Bumblebee-Project/Bumblebee/issues/749#issuecomment-216352740" rel="external">source</a></em></p>
<h3 id="errorcannot-access-secondary-gpu---error-xorg-ee-failed-to-load-module-mouse-module-does-not-exist-0">[ERROR]Cannot access secondary GPU - error: [XORG] (EE) Failed to load module &ldquo;mouse&rdquo; (module does not exist, 0)</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>NOTE</strong> : Cette erreur peut-être générée par un des différents points suivants…
veuillez les vérifier un par un, pas tous en même temps, cela ne sert à rien.
Une fois qu&rsquo;un point est vérifié/corrigé, <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrez le service</a>
et essayez à nouveau votre commande. <br>
Si cela ne fonctionne pas, passez au point suivant qui peut aider à la résolution,
et répétez le même processus de vérification/modification puis redémarrage
du service adéquat - <strong>bien comprendre et accepter que cela ne réglera pas
forcément votre problème !</strong></div>

<h4 id="vérifier-xserver-xorg-input-mouse">Vérifier xserver-xorg-input-mouse</h4>
<p>Vérifiez l&rsquo;installation du paquet <strong>xserver-xorg-input-mouse</strong>, si ce n&rsquo;est pas
le cas, faites-le !</p>
<h4 id="vérifier-le-fichier-xorgconfnvidia">Vérifier le fichier xorg.conf.nvidia</h4>
<p>Vérifiez le fichier <code>/etc/bumblebee/xorg.conf.nvidia</code>.</p>
<h4 id="vérifier-votre-identifiant-pci">Vérifier votre identifiant PCI</h4>
<p>Vérifiez que votre <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#erreur-identifiant-buspci">identifiant de Bus PCI</a> soit
correctement écrit !</p>
<h3 id="errorcannot-access-secondary-gpu---error-xorg-ee-no-devices-detected">[ERROR]Cannot access secondary GPU - error: [XORG] (EE) No devices detected</h3>
<p>Ouvrez le fichier <code>/etc/bumblebee/xorg.conf.nvidia</code>, et modifiez l&rsquo;option BusID.
Vous trouverez cette information par l&rsquo;usage de la commande <code>lsusb</code>…</p>
<p>voir le chapitre <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#verifications">vérifications</a> !</p>
<h3 id="errorcannot-access-secondary-gpu---error-xorg-ee-problem-parsing-the-config-file">[ERROR]Cannot access secondary GPU - error: [XORG] (EE) Problem parsing the config file</h3>
<p><strong>Vérifiez le fichier de configuration que vous venez de modifier !!!</strong></p>
<p>Que ce soit <code>/etc/bumblebee/xorg.config.nvidia</code> ou <code>/etc/bumblebee/xorg.config.nouveau</code>,
vous avez créé/modifié une section, et oublié/supprimé par erreur, de fermer
correctement la section, voire une section est mal écrite !</p>
<h3 id="errorcould-not-connect-to-bumblebee-daemon---is-it-running">[ERROR]Could not connect to bumblebee daemon - is it running?</h3>
<p>Vérifiez que le <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">service Bumblebee</a> soit
fonctionnel !</p>
<h3 id="errorunknown-acceldisplay-bridge">[ERROR]Unknown accel/display bridge:</h3>
<p>Le &ldquo;pont&rdquo; <em>(&lsquo;bridge&rsquo; en anglais)</em> que vous cherchez à utiliser avec
l&rsquo;option <code>-b</code> d&rsquo;optirun n&rsquo;existe pas. <strong>Modifiez votre commande !!!</strong></p>
<h3 id="erroryouve-no-permission-to-communicate-with-the-bumblebee-daemon-try-adding-yourself-to-the-bumblebee-group">[ERROR]You&rsquo;ve no permission to communicate with the Bumblebee daemon. Try adding yourself to the &lsquo;bumblebee&rsquo; group</h3>
<p>Ce message d&rsquo;erreur vous informe que votre identifiant utilisateur semble
ne pas être ajouté <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#ajout-groupe-bumblebee">groupe bumblebee</a>.</p>
<p><strong>Ajoutez-le !</strong></p>
<h3 id="fallen-off-the-bus">fallen off the bus</h3>

<div class="tab-info i-info">Info</div><div class="alert alert-info" role="alert"><strong>NOTE</strong> : Cette erreur peut-être générée par un des différents points suivants…
veuillez les vérifier un par un, pas tous en même temps, cela ne sert à rien.
Une fois qu&rsquo;un point est vérifié/corrigé,
<a href="/fr/sys/debian/nvidia-optimus-bumblebee/#redemarrage-du-service-bumblebeed">redémarrez le service</a> et
essayez à nouveau votre commande. <br>
Si cela ne fonctionne pas, passez au point suivant qui peut aider à la résolution,
et répétez le même processus de vérification/modification puis redémarrage
du service adéquat - <strong>bien comprendre et accepter que cela ne réglera pas
forcément votre problème !</strong></div>

<p><strong>Vérifiez la sortie dmesg !</strong></p>
<p>Si <code>dmesg</code> vous informe du souci GPU suivant <code>fallen off the bus</code>, il y a
deux manières de régler le problème :</p>
<h4 id="test-rcu_idle_gp_delay-1">Test &ldquo;rcu_idle_gp_delay &laquo;&lt;1&rdquo;</h4>
<p>Testez la commande suivante, avant le lancement d&rsquo;optirun : <br>
<code>:# tee /sys/module/rcutree/parameters/rcu_idle_gp_delay &lt;&lt;&lt;1</code></p>
<p>Si cela fonctionne en effet correctement, modifiez le fichier <code>/etc/default/grub</code>
pour ajouter l&rsquo;information suivante à la ligne de commande <code>GRUB_CMDLINE_LINUX_DEFAULT : rcutree.rcu_idle_gp_delay=1</code>.</p>
<p>Mettez-à-jour votre grub et redémarrez votre ordinateur :</p>
<pre tabindex="0"><code>:# update-grub
:# shutdown -r now
</code></pre><h4 id="incompatibilité-kernels-310-à-319">Incompatibilité kernels (3.10 à 3.19)</h4>
<p>L&rsquo;autre solution est de vérifier votre version de kernel linux - en effet
<strong>ce problème concerne les noyaux versions 3.10 à 3.19 !</strong></p>
<p>Soit vous choisissez un noyau antérieur, soit vous upgradez sur un noyau plus
récent !</p>
<p><em>Il semble que ce soit surtout un bogue Nvidia… cf <a href="https://github.com/Bumblebee-Project/Bumblebee/issues/455#issuecomment-22497464" rel="external">Bumblebee issue 445</a></em></p>
<h3 id="error-while-loading-shared-libraries-libturbojpegso">error while loading shared libraries: libturbojpeg.so</h3>
<p>L&rsquo;erreur complète est la suivante : <br>
<code>error while loading shared libraries: libturbojpeg.so: cannot open shared object file: No such file or directory</code></p>
<p>Si vous avez une architecture <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#architecture-32-bits">32</a> ou <a href="/fr/sys/debian/nvidia-optimus-bumblebee/#architecture-64-bits">64</a>
bits :</p>
<h4 id="architecture-32-bits">architecture 32 bits</h4>
<p>Si votre architecture est 32 bits, tapez dans votre terminal console préférée,
cette commande avec les droits administrateur : <br>
<code># ln -s /usr/lib/i386-linux-gnu/libturbojpeg.so.0 /usr/lib/i386-linux-gnu/libturbojpeg.so</code></p>
<h4 id="architecture-64-bits">architecture 64 bits</h4>
<p>Si votre architecture est 64 bits, tapez cette commande-ci, toujours avec
les droits administrateur : <br>
<code># ln -s /usr/lib/x86_64-linux-gnu/libturbojpeg.so.0 /usr/lib/x86_64-linux-gnu/libturbojpeg.so</code></p>
<h3 id="modprobefatalmodule-nouveau-in-use">modprobe:FATAL:Module nouveau in use</h3>
<p>Lors de l&rsquo;installation, au tout début, il vous est dit de décharger le module
nouveau. Si le système vous répond l&rsquo;erreur suivante : <code>modprobe:FATAL:Module nouveau in use</code>,
il est intéressant de le désactiver lors du démarrage du noyau.</p>
<p>Ne vous inquiétez pas trop de ce message d&rsquo;erreur, mais plutôt paramétrez
le fichier de configuration de grub <code>/etc/default/grub</code> afin de rajouter
les paramètres noyau suivants <code>nouveau.modeset=0</code> et <code>modprobe.blacklist=nouveau</code>
dans la ligne de configuration relative à <code>GRUB_CMDLINE_LINUX_DEFAULT</code>,
telle que, par exemple : <br>
<code>GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet nouveau.modeset=0 modprobe.blacklist=nouveau&quot;</code></p>
<p>Mettez-à-jour votre grub… et redémarrez votre station.</p>
<p><em><a href="https://fixmynix.com/nvidia-optimus-troubleshooting-in-debain-kali-linux-ubuntu/" rel="external">source</a></em></p>
<h3 id="primus-fatal-failed-to-load-any-of-the-libraries-libglso1">primus: fatal: failed to load any of the libraries: (…)/libGL.so.1</h3>
<p>Lorsque vous exécutez optirun, vous avez le retour d&rsquo;erreur suivant :</p>
<pre tabindex="0"><code>:$ primus: fatal: failed to load any of the libraries: /usr/lib/x86_64-linux-gnu/nvidia/libGL.so.1:/usr/lib/i386-linux-gnu/nvidia/libGL.so.1:/usr/lib/nvidia/libGL.so.1
/usr/lib/x86_64-linux-gnu/nvidia/libGL.so.1: cannot open shared object file: No such file or directory
/usr/lib/i386-linux-gnu/nvidia/libGL.so.1: cannot open shared object file: No such file or directory
/usr/lib/nvidia/libGL.so.1: cannot open shared object file: No such file or directory
</code></pre><p>ou :</p>
<pre tabindex="0"><code>:$ primus: fatal: failed to load any of the libraries: /usr/lib/x86_64-linux-gnu/ nvidia/libGL.so.1:/usr/lib/i386-linux-gnu/nvidia/libGL.so.1:/usr/lib/nvidia/libGL.so.1
/usr/lib/x86_64-linux-gnu/nvidia/libGL.so.1: wrong ELF class: ELFCLASS64
/usr/lib/i386-linux-gnu/nvidia/libGL.so.1: cannot open shared object file: No such file or directory
/usr/lib/nvidia/libGL.so.1: cannot open shared object file: No such file or directory
</code></pre><ol>
<li>La première chose à tester est : <br>
<code>$ primusrun glxgears</code>
<ul>
<li>Si cela fonctionne, alors précéder les commandes non pas avec <em>optirun</em>,
mais <code>primusrun</code>.</li>
<li>Sinon un bogue <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=876033" rel="external">#867033</a> est ouvert… sachez que c&rsquo;est galère
à corriger, parce que même en installant les packages ci-dessous,
vous ne serez pas sûr de résoudre le problème.</li>
</ul>
</li>
<li>Dans un premier temps, vérifiez que vous avez bien installé le package <strong>primus-libs-ia32</strong>.</li>
<li>Vous pouvez essayer l&rsquo;une des solutions suivantes - <em>sachant qu&rsquo;il n&rsquo;y
a aucune garantie de fonctionnement</em> :
<ul>
<li>Exécutez <strong>primusrun</strong> en le préfixant de l&rsquo;option <code>_GLVND_DISALLOW_PATCHING=1</code>,
tel que : <br>
<code>_GLVND_DISALLOW_PATCHING=1 primusrun glxgears</code> - (cf, la réponse <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=876033#22" rel="external">22</a>)</li>
<li>Éditez le fichier <code>/usr/bin/primusrun</code>, pour modifier la ligne <code>PRIMUS_libGL=${PRIMUS_libGL:-'/usr/$LIB/primus'}</code>
par <code>PRIMUS_libGL=${PRIMUS_libGL:-&quot;/usr/$LIB/primus&quot;}</code> - <br>
c&rsquo;est-à-dire changer les simples quotes en doubles quotes - (cf, la réponse <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=876033#59" rel="external">59</a>)</li>
<li>Essayez l&rsquo;installation des packages suivants : <br>
<strong>libgl1-nvidia-glx libgl1-nvidia-glx:i386 nvidia-driver-libs nvidia-driver-libs-i386</strong></li>
</ul>
</li>
</ol>
<h3 id="freezes-diverses">Freezes diverses</h3>
<p>Il existe plusieurs raisons pour lesquelles le portable peut &ldquo;freezer&rdquo;,
essayez les solutions proposées - <em>en anglais</em> :</p>
<h4 id="freezes-lors-de-lactivation-du-serveur-graphique">Freezes lors de l&rsquo;activation du serveur graphique</h4>
<ul>
<li><a href="https://github.com/Bumblebee-Project/Bumblebee/issues/764#issuecomment-559980823" rel="external">https://github.com/Bumblebee-Project/Bumblebee/issues/764#issuecomment-559980823</a></li>
<li><a href="https://github.com/Bumblebee-Project/Bumblebee/issues/764#issuecomment-612384824" rel="external">https://github.com/Bumblebee-Project/Bumblebee/issues/764#issuecomment-612384824</a></li>
</ul>
<h4 id="freezes-au-boot">Freezes au boot</h4>
<ul>
<li><a href="https://github.com/Bumblebee-Project/Bumblebee/issues/1036#issuecomment-521974873" rel="external">https://github.com/Bumblebee-Project/Bumblebee/issues/1036#issuecomment-521974873</a></li>
<li><a href="https://github.com/Bumblebee-Project/Bumblebee/issues/1036#issuecomment-612779453" rel="external">https://github.com/Bumblebee-Project/Bumblebee/issues/1036#issuecomment-612779453</a></li>
</ul>
<h3 id="test-du-fonctionnement-de-la-batterie">Test du fonctionnement de la batterie</h3>
<p>Pour tester le fonctionnement :</p>
<ol>
<li>vous pouvez procéder ainsi en mode terminal : \</li>
</ol>
<pre tabindex="0"><code>:$ cat /proc/acpi/bbswitch
0000:01:00.0 OFF
</code></pre><ol start="2">
<li>Lancement d&rsquo;optirun :</li>
</ol>
<pre tabindex="0"><code>:$ optirun glxgears &gt; /dev/null &amp;
[1] 4785
</code></pre><ol start="3">
<li>Vérification de bbswitch :</li>
</ol>
<pre tabindex="0"><code>:$ cat /proc/acpi/bbswitch
0000:01:00.0 ON
</code></pre><ol start="4">
<li>Arrêt d&rsquo;optirun, par l&rsquo;appui simultanée des touches <kbd>CTRL+C</kbd>
 :</li>
</ol>
<pre tabindex="0"><code>[VGL] ERROR: in readback--
[VGL] 246: Window has been deleted by window manager

[1]+ Termine 1 optirun glxgears &gt; /dev/null
</code></pre><ol start="5">
<li>Après avoir fermé la fenêtre de glxgears :</li>
</ol>
<pre tabindex="0"><code>:$ cat /proc/acpi/bbswitch
0000:01:00.0 OFF
</code></pre><h2 id="documentations">Documentations</h2>
<ul>
<li>Vous pouvez retrouver un complément d&rsquo;informations sur la <a href="http://wiki.debian.org/fr/Bumblebee" rel="external">page wiki du projet Debian</a>…</li>
<li>Sur le forum Debian-fr.org, à-partir du 23 août 2019, j&rsquo;ai écrit ce complément d&rsquo;informations titré
<strong><a href="https://www.debian-fr.org/t/doc-nvidia-optimus-bumblebee-dans-quel-etat-gere-infos/79959" rel="external">&quot;[Doc] Nvidia Optimus + Bumblebee : Dans quel état gère… [Infos]&quot;</a></strong>
qui montre à quel point la situation devient compliquée… <br>
je l&rsquo;ai maintenu jusqu&rsquo;en début 2020 - je n&rsquo;ai de fait plus ce type
d&rsquo;architecture graphique !</li>
<li>J&rsquo;ai écrit ce tutoriel la première fois en Janvier 2013, pour la <a href="https://wiki.debian-fr.xyz/NVidia_Optimus_Bumblebee" rel="external">communauté Debian-fr.xyz</a> ;-)</li>
<li>J&rsquo;ai collaboré à l&rsquo;écriture de cette <a href="https://debian-facile.org/doc:materiel:cartes-graphique:nvidia:optimus" rel="external">page wiki</a> pour la communauté Debian-Facile.org,
depuis mai 2016.</li>
</ul>
<hr>
]]></content>
        <summary type="html"><![CDATA[Comment faire fonctionner la technologie Optimus de Nvidia grâce au projet Bumblebee sous Debian !]]></summary>
        <published>2013-01-14T21:00:00+02:00</published>
        <updated>2025-11-10T10:51:13+01:00</updated>
    </entry>
    
</feed>

